当前位置: 首页 > news >正文

望牛墩仿做网站万维网网站

望牛墩仿做网站,万维网网站,什么是网站前置审批,答题网站怎么做Flutter网络请求框架Dio源码分析以及封装--Cookie管理分析 前言问题如何使用CookieJarCookieManagerPersistCookieJar总结 前言 上一篇文章我们简单分析了一下Dio发出请求时的大致工作流程#xff0c;这个只是Dio最基本的功能#xff0c;而且我们还没有分析走到httpClientA… Flutter网络请求框架Dio源码分析以及封装--Cookie管理分析 前言问题如何使用CookieJarCookieManagerPersistCookieJar总结 前言 上一篇文章我们简单分析了一下Dio发出请求时的大致工作流程这个只是Dio最基本的功能而且我们还没有分析走到httpClientAdapter之后的内容。不过不用着急这次我们先接着上一次的内容看一下Dio当中Cookie管理的问题因为之前在项目中碰到了这个问题回过头来再从源码的角度去分析一下算是复盘。 问题 之前碰到的问题是这样的登录接口在登陆成功后会返回一个Cookie给客户端包含在Response的 “set-cookie”Headers属性里。之后在客户端这边调用某些接口时后台需要对Cookie进行验证所以需要把Cookie存到内存甚至硬盘里在请求头里面带上传给后台否则会后台会报请求失败。 由于以前的项目基本上是采取token的方式去做接口鉴权所以这种cookie持久化的方法对我来说有点陌生不过最后还是能想到利用拦截器去做这个事情。Dio允许我们自定义拦截器对请求与返回的参数进行调整我们在onResponse回调方法里从Response里面的headers拿到Cookie再在onRequest里面加到RequestOptions里。原理很简单但是之前自己实现的时候很多细节没有处理好造成了代码的冗余以及不够健壮。 实际上Dio提供了配套的Plugindio_cookie_manager 来帮助我们进行Cookie的管理使用起来也非常的方便。那么这次我们就一起来看一下它是怎么处理这些问题的。 如何使用 首先我们需要导入cookie_manager的库基于项目中用到的2.0.0版本 它又间接依赖cookie_jar3.0.0这个版本 dependencies:dio_cookie_manager: ^2.0.0cookie_jar: ^3.0.0final dio Dio();final cookieJar CookieJar();dio.interceptors.add(CookieManager(cookieJar));如示例中所示我们需要构造一个CookieJar的实例然后将它传入CookieManager的构造方法中最后添加到Dio的拦截器列表中。 CookieJar 我们先来看看CookieJar这个类 /// CookieJar is a cookie manager for http requests。 abstract class CookieJar {factory CookieJar({bool ignoreExpires false}) {return DefaultCookieJar(ignoreExpires: ignoreExpires);}/// Save the cookies for specified uri.Futurevoid saveFromResponse(Uri uri, ListCookie cookies);/// Load the cookies for specified uri.FutureListCookie loadForRequest(Uri uri);Futurevoid deleteAll();Futurevoid delete(Uri uri, [bool withDomainSharedCookie false]);final bool ignoreExpires false; }CookieJar是抽象类最终还是调用了DefaultCookieJar这个类的构造方法 /// [DefaultCookieJar] is a default cookie manager which implements the standard /// cookie policy declared in RFC. [DefaultCookieJar] saves the cookies in RAM, so if the application /// exit, all cookies will be cleared. class DefaultCookieJar implements CookieJar {/// [ignoreExpires]: save/load even cookies that have expired.DefaultCookieJar({this.ignoreExpires false});...}DefaultCookieJar是CookieJar的一种默认实现按照http的格式将cookie从Request与Response中解析出来并保存在Ram中。 CookieManager 接着来看看CookieManager这个类 /// Dont use this class in Browser environment class CookieManager extends Interceptor {final CookieJar cookieJar;CookieManager(this.cookieJar); 、 dartoverridevoid onRequest(RequestOptions options, RequestInterceptorHandler handler) {cookieJar.loadForRequest(options.uri).then((cookies) {var cookie getCookies(cookies);if (cookie.isNotEmpty) {options.headers[HttpHeaders.cookieHeader] cookie;}handler.next(options);}).catchError((e, stackTrace) {var err DioError(requestOptions: options, error: e);err.stackTrace stackTrace;handler.reject(err, true);});}static String getCookies(ListCookie cookies) {return cookies.map((cookie) ${cookie.name}${cookie.value}).join(; );}构造的cookieJar传进来后在onRequest方法里面调用loadForRequest方法获取格式化后的Cookie将他们转化为请求需要的格式然后设置在请求头里之后继续执行下面的拦截器的逻辑。 overridevoid onResponse(Response response, ResponseInterceptorHandler handler) {_saveCookies(response).then((_) handler.next(response)).catchError((e, stackTrace) {var err DioError(requestOptions: response.requestOptions, error: e);err.stackTrace stackTrace;handler.reject(err, true);});}Futurevoid _saveCookies(Response response) async {var cookies response.headers[HttpHeaders.setCookieHeader];if (cookies ! null) {await cookieJar.saveFromResponse(response.requestOptions.uri,cookies.map((str) Cookie.fromSetCookieValue(str)).toList(),);}}onResponse也类似拿到Cookie之后调用saveFromResponse格式化保存起来之后继续执行下面的拦截器的逻辑。 当然正常的顺序应该是先在onResponse拿到Cookie之后再在onResponse使用。 PersistCookieJar 如果想对Cookie进行持久化处理可以考虑使用PersistCookieJar final Directory appDocDir await getApplicationDocumentsDirectory();final String appDocPath appDocDir.path;final jar PersistCookieJar(ignoreExpires: true,storage: FileStorage(appDocPath /.cookies/),);dio!.interceptors.add(CookieManager(jar));/// [PersistCookieJar] is a cookie manager which implements the standard /// cookie policy declared in RFC. [PersistCookieJar] persists the cookies in files, /// so if the application exit, the cookies always exist unless call [delete] explicitly. class PersistCookieJar extends DefaultCookieJar {////// [persistSession]: Whether persisting the cookies that without/// expires or max-age attribute;/// If false, the session cookies will be discarded;/// otherwise, the session cookies will be persisted.////// [ignoreExpires]: save/load even cookies that have expired.////// [storage]: Defaults to FileStoragePersistCookieJar({this.persistSession true,bool ignoreExpires false,Storage? storage}): super(ignoreExpires: ignoreExpires) {this.storage storage ?? FileStorage();}为了实现持久化引入了一个Storage类默认实现是FileStorage文件存储也可以自己实现其他方式。 overrideFutureListCookie loadForRequest(Uri uri) async {await _checkInitialized();await _load(uri);return super.loadForRequest(uri);}PersistCookieJar最终也调用了DefaultCookieJar的loadForRequest方法但是在那之前还执行了两个方法我们一个一个看 Futurevoid _checkInitialized({bool force false}) async {if (force || !_initialized) {await storage.init(persistSession, ignoreExpires);// Load domain cookiesvar str await storage.read(DomainsKey);...}执行了storage的init与read方法 overrideFuturevoid init(bool persistSession, bool ignoreExpires) async {_curDir dir ?? ./.cookies/;if (!_curDir!.endsWith(/)) {_curDir _curDir! /;}_curDir _curDir! ie${ignoreExpires ? 1 : 0}_ps${persistSession ? 1 : 0}/;await _makeCookieDir();}Futurevoid _makeCookieDir() async {final directory Directory(_curDir!);if (!directory.existsSync()) {await directory.create(recursive: true);}}init方法主要是检查传入的保存目录是否存在不存在就创建。 read方法与load方法分别将文件中数据读取并存入内存中domainCookies与hostCookies Futurevoid _load(Uri uri) async {final host uri.host;if (_hostSet.contains(host) hostCookies[host] null) {var str await storage.read(host);overrideFuturevoid saveFromResponse(Uri uri, ListCookie cookies) async {await _checkInitialized();if (cookies.isNotEmpty) {await super.saveFromResponse(uri, cookies);if (cookies.every((Cookie e) e.domain null)) {await _save(uri);} else {await _save(uri, true);}}}先检查有无保存目录再看是否传入cookies若有直接调用DefaultCookieJar的saveFromResponse然后调用_save方法 Futurevoid _save(Uri uri, [bool withDomainSharedCookie false]) async {final host uri.host;if (!_hostSet.contains(host)) {_hostSet.add(host);await storage.write(IndexKey, json.encode(_hostSet.toList()));}final cookies hostCookies[host];if (cookies ! null) {await storage.write(host, json.encode(_filter(cookies)));}if (withDomainSharedCookie) {var filterDomainCookies domainCookies.map((key, value) MapEntry(key, _filter(value)));await storage.write(DomainsKey, json.encode(filterDomainCookies));}}根据Cookie层级依次写入到文件中。 总结 CookieManager与CookieJar的整个工作流程就基本分析完了可以看到整个流程非常清晰代码也很简洁健壮性也很好这次源码学习让我对代码编写的理解有深入了一些。那么下次我们一起来看看如何封装Dio让我们平时使用起来更便捷。
http://www.yingshimen.cn/news/138266/

相关文章:

  • 南宁定制网站建设中国空间站首次太空授课
  • 网站密码管理制度vs进行网站建设
  • 做网站要具备哪些济南好的网站建设公司
  • 开个做网站要多少钱产品价格的网站建设
  • 临海受欢迎营销型网站建设手机模板网站
  • 服装公司网站建设外贸网站源码是什么
  • 分类目录网站程序网站做交叉连接
  • 音乐网站设计素材保证量身定制的营销型网站
  • 创建一个网站的条件有哪些wordpress 豆瓣电影
  • 如何做公司宣传网站wordpress 升级 无法创建目录
  • 企业官方网站怎么做介绍自己做的电影网站
  • 网站备案的原则贺州网站seo
  • php ajax网站开发在线设计平台的优缺点
  • 建设网站可选择的方案网站建设人员组成
  • 成都设计院排行网站制作找云优化
  • 周末做兼职上什么网站找上海网站建设公司四叶互联
  • 做搜狗网站优化首设计师兼职网站
  • 沧州企业网站建设方案邢台新闻最新事件
  • 搭建网站的步骤如何注册公司多少钱
  • 有了php源码怎么做网站网站建设用户体验
  • 网站和网页的关系网站推广和seo
  • dede网站模板页在什么文件夹wordpress 自适应cms主题
  • 站酷网vi设计天河做网站要多少钱
  • 怎么百度上搜到自己的网站机票网站手机版建设
  • 怎样创建购物网站如何在淘宝网上卖东西
  • 怎样删除网站虚拟主机内容网上做设计的网站有哪些
  • 小学生做网站软件惠州网站建设哪家便宜
  • 网站建设计划方案模板网站报备之后如何建设网站
  • 营销网站做得好的公司怎么免费建立网站
  • 网站子域名怎么设置广州网站设计公司哪里济南兴田德润怎么联系