在Flutter中进行网络申请时,咱们能够应用的库有3个,即Http申请库、HttpClient申请库和Dio申请库(具体介绍请参考:Flutter开发之Http网络申请),应用得最多的就是Dio申请库。因为相比Http申请库和HttpClient申请库,Dio库不仅反对常见的网络申请,还反对Restful API、FormData、拦截器、申请勾销、Cookie治理、文件上传/下载、超时等操作。

不过,默认状况下,Dio进行网络申请时是不反对抓包的,所以如果要进行抓包,就须要对Dio进行申请封装,并编写代理代码。上面是代理的几种写法:

办法一

咱们能够间接在Dio外面设置ip以及端口,通过硬编码的形式进行代理,代码如下:

(_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =          (client) {        //这一段是解决安卓https抓包的问题        client.badCertificateCallback =            (X509Certificate cert, String host, int port) {          return Platform.isAndroid;        };        client.findProxy = (uri) {          return "PROXY 代理ip:代理port";        };      };

不过,这种硬编码方式,写得太死,不够灵便,每次更改代理都须要打包。

办法二

间接在原生插件获取手代理ip和代理端口,不过Android比拟难,上面是iOS的实现。

 //主动获取手机代理  NSDictionary *proxySettings = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());           NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:call.arguments]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));           NSString *hostName = proxySettings[@"HTTPSProxy"];           NSString *portName = [NSString stringWithFormat:@"%@",proxySettings[@"HTTPPort"]];           long HTTPEnable = [proxySettings[@"HTTPEnable"] longValue];           if (HTTPEnable==0) {               hostName = @"";           }

办法三

除了下面的硬编码方式外,咱们还能够采纳scheme协定的形式传入代理ip和代理端口。此办法的步骤如下:
1,注册本人的URL Scheme,例如:scheme://
2,定义参数规定,例如:scheme://tiaoshi?host=10.0.206.163
3,引入flutter插件:uni_links: ^0.2.0
4,flutter监听解析参数,并在dio外面设置代理
5,应用[草料]https://cli.im生成一个二维码:内容:scheme://tiaoshi?host=10.0.206.163
6,应用原生相机扫码进入app就能够抓包

上面是波及的代码,Flutter代码如下:

Future<Null> initUniLinks() async {       // 监听插件scheme数据      getLinksStream().listen((String link) {        link =  Uri.decodeComponent(link);        if(link.contains("scheme://")){          String type = getTypeStr(link);          String param = link.replaceAll("scheme://$type?", "");          Map dict = getUrlParams(param);          if(type=="tiaoshi"){//设置抓包代理            String host = dict["host"];            String port = dict["port"];            //这里是网络申请封装            Net.setHttpProxy(host,port==null?"8888":port);           }        }      // Parse the link and warn the user, if it is not correct    }, onError: (err) {      // Handle exception by warning the user their action did not succeed    });  }//获取scheme 要解决的业务类型  String getTypeStr(String link){    List params = link.split("?");    String typeStr = params[0];    typeStr =  typeStr.replaceAll("scheme://", "");    return typeStr;  }//url参数转map  Map getUrlParams(String paramStr) {    Map map = Map();    List params = paramStr.split("&");    for(int i=0;i<params.length;i++){      String str = params[i];      List arr = str.split("=");      map[arr[0]]= arr[1];    }    return map;  }

代理层代码:

static void setHttpProxy(String host,String port) {    Application.httpProxy = host+':'+port;    _initDio();  }static Future<void> _initDio() async {    DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();    if (Platform.isAndroid) {      _androidInfo = await deviceInfo.androidInfo;    } else if (Platform.isIOS) {      _iosInfo = await deviceInfo.iosInfo;    }        _dio = Dio(BaseOptions(      contentType: 'application/json',      baseUrl: Config.BASE_URL,    ));    _dio.options.receiveTimeout = 5000;    _dio.options.connectTimeout = 10000;    if (Application.httpProxy.length != 0) {      (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =          (client) {        //这一段是解决安卓https抓包的问题        client.badCertificateCallback =            (X509Certificate cert, String host, int port) {          return Platform.isAndroid;        };       //这是抓包代理        client.findProxy = (uri) {          return "PROXY ${Application.httpProxy}";        };      };    }    _dio.interceptors.addAll([      InterceptorsWrapper(        onRequest: (Options options) {          options.headers['DeviceName'] = 'xxxx';          return options;        },        onResponse: (Response res) {          try {          ...            return res;          } catch (e) {            return res;          }        },        onError: (DioError e) {          print(e);         }              break;            default:          }          return e;        },      ),    ]);  }static Future<ResponseModel> get(    String path, {    Map<String, dynamic> queryParameters,    Options options,    CancelToken cancelToken,    void Function(int, int) onReceiveProgress,  }) async {    if (_dio == null) {      await _initDio();    }    final res = await _dio.get<ResponseModel>(      path,      queryParameters: queryParameters,      options: options,      cancelToken: cancelToken,      onReceiveProgress: onReceiveProgress,    );    return res.data;  }  static Future<ResponseModel> post(    String path, {    dynamic data,    Map<String, dynamic> queryParameters,    Options options,    CancelToken cancelToken,    void Function(int, int) onSendProgress,    void Function(int, int) onReceiveProgress,  }) async {    if (_dio == null) {      await _initDio();    }    final res = await _dio.post<ResponseModel>(      path,      data: data,      queryParameters: queryParameters,      options: options,      cancelToken: cancelToken,      onSendProgress: onSendProgress,      onReceiveProgress: onReceiveProgress,    );    return res.data;  }