dio 使用方法看 https://github.com/flutterchina/dio
记录下dio 配套组件
dio_cookie_manager 管理cookie的
dio_http2_adapter http2 适配器
dio_smart_retry 重试机制
http_certificate_pinning 配置固定证书 比如就不能随意抓包
curl_logger_dio_interceptor curl生成器, 比如可以在终端请求
dio_cache_interceptor 请求缓存
dio_http_cache HTTP 缓存拦截器
pretty_dio_logger 拦截器记录网络调用
分析post
Future<Response<T>> post<T>( String path, { data, Map<String, dynamic>? queryParameters, Options? options, CancelToken? cancelToken, ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress, }) { return request<T>( //路径 path, //数据 data: data, //用来配置http信息(传入会覆盖公共的BaseOptions信息) options: checkOptions('POST', options), //查询参数 queryParameters: queryParameters, //token 用来取消请求 cancelToken: cancelToken, //请求进度 onSendProgress: onSendProgress, //接受进度 onReceiveProgress: onReceiveProgress, ); }
接着看
Future<Response<T>> request<T>( String path, { data, Map<String, dynamic>? queryParameters, CancelToken? cancelToken, Options? options, ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress, }) async { options ??= Options(); var requestOptions = options.compose( this.options, path, data: data, queryParameters: queryParameters, onReceiveProgress: onReceiveProgress, onSendProgress: onSendProgress, cancelToken: cancelToken, ); requestOptions.onReceiveProgress = onReceiveProgress; requestOptions.onSendProgress = onSendProgress; requestOptions.cancelToken = cancelToken; if (_closed) { throw DioError( requestOptions: requestOptions, error: "Dio can't establish new connection after closed.", ); } return fetch<T>(requestOptions); }
继续查看
RequestOptions compose( BaseOptions baseOpt, String path, { data, Map<String, dynamic>? queryParameters, CancelToken? cancelToken, Options? options, ProgressCallback? onSendProgress, ProgressCallback? onReceiveProgress, }) { var query = <String, dynamic>{}; //添加base查询的数据 query.addAll(baseOpt.queryParameters); //添加额外数据 if (queryParameters != null) query.addAll(queryParameters); //获取小写比较的map var _headers = caseInsensitiveKeyMap(baseOpt.headers); _headers.remove(Headers.contentTypeHeader); String? _contentType; if (headers != null) { _headers.addAll(headers!); _contentType = _headers[Headers.contentTypeHeader] as String?; } var _extra = Map<String, dynamic>.from(baseOpt.extra); if (extra != null) { _extra.addAll(extra!); } var _method = (method ?? baseOpt.method).toUpperCase(); var requestOptions = RequestOptions( ...省略 ); requestOptions.onReceiveProgress = onReceiveProgress; requestOptions.onSendProgress = onSendProgress; requestOptions.cancelToken = cancelToken; requestOptions.contentType = _contentType ?? contentType ?? baseOpt.contentTypeWithRequestBody(_method); return requestOptions; }
Future<Response<T>> fetch<T>(RequestOptions requestOptions) async { final stackTrace = StackTrace.current; if (requestOptions.cancelToken != null) { //赋值 requestOptions.cancelToken!.requestOptions = requestOptions; } //标记返回的数据格式: 文本 json 流 if (T != dynamic && !(requestOptions.responseType == ResponseType.bytes || requestOptions.responseType == ResponseType.stream)) { if (T == String) { requestOptions.responseType = ResponseType.plain; } else { requestOptions.responseType = ResponseType.json; } } //嵌套函数 各个拦截器的处理方法 FutureOr Function(dynamic) _requestInterceptorWrapper( InterceptorSendCallback interceptor, ) { return (dynamic _state) async { // 来自 var future = Future<dynamic>(() => InterceptorState(requestOptions)); var state = _state as InterceptorState; //默认为ture if (state.type == InterceptorResultType.next) { //如果cancelToken != null返回 throw DioError return listenCancelForAsyncTask( requestOptions.cancelToken, //否则运行 Future(() { //检查是否QueuedInterceptor 是的 wait 一个一个运行 return checkIfNeedEnqueue(interceptors.requestLock, () { //否则运行 var requestHandler = RequestInterceptorHandler(); //回调 interceptor(state.data as RequestOptions, requestHandler); //返回Future<InterceptorState> return requestHandler.future; }); }), ); } else { return state; } }; } ...省略 //开启一个请求 var future = Future<dynamic>(() => InterceptorState(requestOptions)); //遍历拦截器Request interceptors.forEach((Interceptor interceptor) { var fun = interceptor is QueuedInterceptor ? interceptor._handleRequest : interceptor.onRequest; future = future.then(_requestInterceptorWrapper(fun)); }); // future 经过自己处理的onRequest ->Future<InterceptorState> // _requestInterceptorWrapper()返回一个(dynamic _state) 匿名方法,取InterceptorState 再次判断cancelToken 检查队列checkIfNeedEnqueue 然后回调 最后再次返回future future = future.then(_requestInterceptorWrapper(( RequestOptions reqOpt, RequestInterceptorHandler handler, ) { requestOptions = reqOpt; //请求http _dispatchRequest(reqOpt) .then((value) => handler.resolve(value, true)) .catchError((e) { handler.reject(e as DioError, true); }); })); //后面的就和前面一样的执行方法。这时候的future 已经带有响应的data ...省略 //结束返回 return future.then<Response<T>>((data) { return assureResponse<T>( data is InterceptorState ? data.data : data, requestOptions, ); }).catchError((err, _) { var isState = err is InterceptorState; if (isState) { if ((err as InterceptorState).type == InterceptorResultType.resolve) { return assureResponse<T>(err.data, requestOptions); } } ...省略 }); }