dio 配置抓包代理

需要通过以下代码才能设置代理。

  //是否开启抓包功能static const bool isProxyEnable = true;//设置代理服务器地址和端口static const String proxy = "192.168.7.134:8888";init(){...
//配置可以通过Fiddler抓包if(isProxyEnable){(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =(client) {client.badCertificateCallback =(X509Certificate cert, String host, int port) {return isProxyEnable &&DebugModelUtil.isDebugMode;};client.findProxy = (url) {return  'PROXY $proxy' ;};};}  }

以上方法使用了一个工具用来判断app在debug模式还是release模式下

import 'package:flutter/foundation.dart';bool _debug = kDebugMode; //constant下的一个常量bool _release = kReleaseMode; //constant下的一个常量///用于判断是否在debug模式下
class DebugModelUtil {static bool get isDebugMode {return _debug;}
}

post请求 参数需要放在data中

错误情况
测试代码如下,如果放在queryParameters 中,将会拼接到url中。

 Map<String, dynamic> params = {};params['name']='zhangshan&a b c';params['age']=24;params['language']='中文';HttpUtil.dio.post('http://192.168.1.1',queryParameters: params,);

fiddler抓包如下

正确情况

测试代码

                  Map<String, dynamic> params = {};params['name'] = 'zhangshan&a b c';params['age'] = 24;params['language'] = '中文';HttpUtil.dio.post('http://192.168.1.1',data: params,);

fiddler抓包结果

指定content-type

在默认情况下,dio的content-type使用的是 application/json; charset=utf-8 而要使用其他的content-type。需要如下使用,有两种方法

通过header指定

代码如下

                  Map<String, dynamic> params = {};params['name'] = 'zhangshan&a b c';params['age'] = 24;params['language'] = '中文';HttpUtil.dio.post('http://192.168.1.1',data: params,options: Options(headers: {Headers.contentTypeHeader:Headers.formUrlEncodedContentType}));

抓包结果如下:

通过content-type指定

代码如下

              Map<String, dynamic> params = {};params['name'] = 'zhangshan&a b c';params['age'] = 24;params['language'] = '中文';HttpUtil.dio.post('http://192.168.1.1',data: params,options: Options(contentType: 'application/x-www-form-urlencoded'));

抓包结果

以上两种方法需要注意的点如下

  • 内容不一样,header中使用的是一个Headers中的常量内容是application/x-www-form-urlencoded;charset=utf-8 而contentType中并没有charset这部分。

  • 如果指定了类型为application/x-www-form-urlencoded 则dio会对data中的数据自动编码。比如中文和空格。在抓包结果中可以看到。

  • multipart/form-data 不支持这种方式,下面会介绍。

使用 multipart/form-data (附带上传文件)

上面介绍的方法对multipart/form-data 这种类型不支持。需要单独编码。因为这种类型比较复杂,还可以上传文件。

测试代码

                     Map params = {};params['name']='zhangshan&a b c';params['age']=24;params['language']='中文';//上传文件var mtp= MultipartFile.fromString('abcdef',filename: 'text.file') ;//携带其他参数var formData = FormData.fromMap({'file':mtp,...params});HttpUtil.dio.post('http://newapp.jyb.cn/app_pub/',data: formData,);

抓包结果

MultipartFile类具有很多方便的静态方法,可以很轻松的获取一个文件。

指定返回类型

如果你请求的时候指定了返回类型,dio会自动帮你转化,比如你指定类型为一个json。则拿到的response.data 属性就会是一个Map。 这个主要是通过设置option的responseType来实现的。
代码如下

                  Map params = {};params['name']='zhangshan&a b c';params['age']=24;params['language']='中文';HttpUtil.dio.post('http://newapp.jyb.cn/app_pub/',data: params,options: Options(responseType: ResponseType.json));

附带一个网络访问工具的封装

import 'dart:io';import 'package:connectivity/connectivity.dart';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'package:dio_http_cache/dio_http_cache.dart';
import 'package:dio_log/interceptor/dio_log_interceptor.dart';
import 'package:tibet_wxb/common/http/mock_data_interceptor.dart';
import 'package:tibet_wxb/common/util/dev_model_check.dart';
import 'package:tibet_wxb/common/util/web_util.dart';typedef JsonParseFun<T> = T Function(Map<String, dynamic> json);
typedef StringParseFun<T> = T Function(String str);enum DioMethod {get,post,put,delete,patch,head,
}class HttpUtil {static late Dio _dio;static const int _connectTimeout = 30 * 1000; //15sstatic const int _receiveTimeout = 30 * 1000;static const int _sendTimeout = 30 * 1000;static DioCacheManager? _dioCacheManager;//是否开启抓包功能static const bool isProxyEnable = true;//设置代理服务器地址和端口static const String proxy = "192.168.7.134:8888";static init() {/// 全局属性:请求前缀、连接超时时间、响应超时时间var options = BaseOptions(/// 请求的Content-Type,默认值是"application/json; charset=utf-8"./// 如果您想以"application/x-www-form-urlencoded"格式编码请求数据,/// 可以设置此选项为 `Headers.formUrlEncodedContentType`,  这样[Dio]就会自动编码请求体.responseType: ResponseType.json,validateStatus: (status) {// 不使用http状态码判断状态,使用AdapterInterceptor来处理(适用于标准REST风格)return true;},connectTimeout: _connectTimeout,receiveTimeout: _receiveTimeout,sendTimeout: _sendTimeout,);_dio = Dio(options);//添加网络日志监听_dio.interceptors.add(DioLogInterceptor());//添加网络缓存if (PlatformUtil.isInMobile) {_dioCacheManager = DioCacheManager(CacheConfig());_dio.interceptors.add(_dioCacheManager!.interceptor);}//添加对模拟数据的处理_dio.interceptors.add(MockDataInterceptor());//配置可以通过Fiddler抓包if(isProxyEnable){(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =(client) {client.badCertificateCallback =(X509Certificate cert, String host, int port) {return isProxyEnable &&DebugModelUtil.isDebugMode;};client.findProxy = (url) {return  'PROXY $proxy' ;};};}}static void clearCache() {_dioCacheManager!.clearAll();}static Dio get dio{return _dio;}//只获取stringstatic Future<String> requestString<T>(String path, {DioMethod method = DioMethod.get,Map<String, dynamic>? params,Map<String, dynamic>? headers,data,CancelToken? cancelToken,Options? options,ProgressCallback? onSendProgress,ProgressCallback? onReceiveProgress,}) async {options??=Options();var str = await request<String>(path,stringParseFun: (str)=>str,method: method,params: params,headers: headers,data: data,cancelToken: cancelToken,options: options.copyWith(responseType: ResponseType.plain),onSendProgress: onSendProgress,onReceiveProgress: onReceiveProgress,);return str ?? "";}/// 对网络访问的统一封装/// 如果请求的数据是string的话,那么需要传入stringParseFun 方法/// 如果返回的数据格式是json的话,需要传入jsonParseFun 方法static Future<T?> request<T>(String path, {JsonParseFun<T>? jsonParseFun,StringParseFun<T>? stringParseFun,DioMethod method = DioMethod.get,Map<String, dynamic>? params,Map<String, dynamic>? headers,data,CancelToken? cancelToken,Options? options,ProgressCallback? onSendProgress,ProgressCallback? onReceiveProgress,}) async {const _methodValues = {DioMethod.get: 'get',DioMethod.post: 'post',DioMethod.put: 'put',DioMethod.delete: 'delete',DioMethod.patch: 'patch',DioMethod.head: 'head'};options ??= Options();options=options.copyWith(method: _methodValues[method],headers: headers);print('options content type is ${options.contentType}');try {Response response;response = await _dio.request(path,data: data,queryParameters: params,cancelToken: cancelToken,options: options,onSendProgress: onSendProgress,onReceiveProgress: onReceiveProgress);if (response.statusCode == 200) {if (stringParseFun != null) {return stringParseFun(response.data);}if (response.data is Map && jsonParseFun != null) {return jsonParseFun(response.data);}} else {throw DioError(requestOptions: response.requestOptions,type: DioErrorType.other,response: response,error: "服务器错误:状态码为" + response.statusCode.toString());}} on DioError catch (e) {onErrorInterceptor(e);rethrow;}}// 对错误添加更好的语义化处理static void onErrorInterceptor(DioError err) async {// 异常分类switch (err.type) {// 4xx 5xx responsecase DioErrorType.response:err.requestOptions.extra["errorMsg"] = err.response?.data ?? "连接异常";break;case DioErrorType.connectTimeout:err.requestOptions.extra["errorMsg"] = "连接超时";break;case DioErrorType.sendTimeout:err.requestOptions.extra["errorMsg"] = "发送超时";break;case DioErrorType.receiveTimeout:err.requestOptions.extra["errorMsg"] = "接收超时";break;case DioErrorType.cancel:err.requestOptions.extra["errorMsg"] =err.message.isNotEmpty ? err.message : "取消连接";break;case DioErrorType.other:default:var connectivityResult = await (Connectivity().checkConnectivity());//判断是否有网络if (connectivityResult == ConnectivityResult.none) {err.requestOptions.extra["errorMsg"] = "网络未连接";break;}err.requestOptions.extra["errorMsg"] = "连接异常";break;}}
}

对模拟数据的支持

使用拦截器实现

import 'package:dio/dio.dart';
import 'package:flutter/services.dart';
import 'dart:convert';class MockDataInterceptor extends Interceptor{static const String local_path='http://127.0.0.1/';@overrideFuture<void> onRequest(RequestOptions options, RequestInterceptorHandler handler) async {var path = options.path;if(path.startsWith(local_path)){try{String relPath= "assets/mock_data/"+path.substring(local_path.length);String jsonStr=await rootBundle.loadString(relPath);Response response=Response(requestOptions: options);response.data=json.decode(jsonStr);response.statusCode=200;handler.resolve(response);}catch (e){DioError dioError=DioError(requestOptions: options,error: "解析模拟数据错误$e");handler.reject(dioError);}}else{handler.next(options);}}
}

Flutter dio 使用 注意事项相关推荐

  1. Flutter Dio的简易封装和demo

    flutter_net_demo 一个简单的flutter dio的封装, 包括: 日志打印, 网络进度, 返回json转bean, get post upload方法的封装, 简易可直接运行的dem ...

  2. Flutter Dio 网络接口与请求数据

    Flutter Dio 网络接口与请求数据 想了想,感觉没什么好说的,像什么get,post,delete,download啥的,基本插件的使用文档都有,没什么好说的,但是我们实际项目写的时候,可不能 ...

  3. Flutter - dio 简单二次封装

    demo 地址: https://github.com/iotjin/jh_flutter_demo Flutter Dio简单二次封装和自定义Header Flutter Dio二次封装 Flutt ...

  4. Flutter —— dio

    Flutter -- dio 1. 关于import 2. pubspec 3. Dio 4. 替换项目三方库 1. 关于import import 中 as关键字来给他起了个别名来避免类名.方法名冲 ...

  5. Flutter dio XMLHttpRequest error

    Flutter dio XMLHttpRequest error 原文:https://blog.csdn.net/weixin_44259356/article/details/105601933 ...

  6. flutter dio+rxdart

    线上flutter 接口请求基本架构(线上实际项目搭建 不多讲直接上代码) 首先添加库: pubspec.yaml 目录下: dio: ^2.1.2 #dio 请求框架rxdart: ^0.21.0 ...

  7. flutter dio 示例

    GIT HUB常常打不开,保存一份以方便随时查看. 示例 发起一个 GET 请求 : Response response; var dio = Dio(); response = await dio. ...

  8. Flutter dio 文件上传下载

    Dio 是Flutter 网络请求的Pub包 Dio除了常用的get post 还可以文件下载 上传等操作 关于文件分片上传 或者文件下载 用到的pub 包 #文件选择file_selector: ^ ...

  9. Flutter Dio包网络请求抓包解决方案

    在Flutter中进行网络请求时,我们可以使用的库有3个,即Http请求库.HttpClient请求库和Dio请求库(详细介绍请参考:Flutter开发之Http网络请求),使用得最多的就是Dio请求 ...

最新文章

  1. 微软发布代码智能新基准数据集CodeXGLUE,多角度衡量模型优劣
  2. MyEclipse极速优化
  3. 计算机科学与技术python方向是什么意思-计算机科学与技术专业大学应该掌握什么样的基本技能?...
  4. LRUCache 具体解释
  5. NoSQL数据库探讨之一 - 为什么要用非关系数据库?
  6. linux find命令详解--转
  7. 数字统计1(数组下标法)
  8. 【H.264/AVC视频编解码技术】第二章【H264码流分析】
  9. pta输出三角形字符阵列c语言,C语言l|博客园作业11
  10. java四则出题判分_java 随机出题四则运算
  11. 扎克伯格拒绝参加加拿大议会 或因藐视罪名被拘留
  12. 哪里有高中教师教学计算机能力培训,04060406_王世红_高中教师信息技术能力的培训.doc...
  13. 《原力计划【第二季】》第 7 周周榜揭晓!!!
  14. C++ 以智能指针管理内存资源
  15. ui-router 之 $state.go
  16. CWE-120: Buffer Copy without Checking Size of Input(不检查输入数据大小就复制缓冲区)
  17. 【科研工具】【MikTex】MikTex安装和使用
  18. 用二叉树表示家谱关系并实现各种查找功能
  19. 华为云迁移工具推荐最佳实践:Xen虚拟化迁移到华为云
  20. html 设置响应X-frame,X-Frame-Options(点击劫持)漏洞分析及web配置修复

热门文章

  1. 20几岁男人应该懂得50件事
  2. VMware一些使用心得
  3. unity开发日记之火箭发射
  4. python调用迅雷下载
  5. linux时间变成英文,查看/修改Linux时区和时间
  6. FPGA学习笔记【FPGA原理与结构】
  7. 数据趣事之父亲节专辑
  8. springboot 配置全局响应数据_SpringBoot如何读取配置文件参数并全局使用
  9. 如何判断对方列表里是不是好友_如何判断qq好友是不是删了你
  10. 【真人手指动画制作软件】万彩手影大师教程 | 详解视频输出设置