Flutter 做应用开发时 Charles 抓不到接口的解决办法

3,903 阅读2分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

Flutter 使用 Charles进行抓包

1.问题

我们在做应用开发的时候,经常需要利用一些工具抓取网络请求接口,这样可以极大的方便接口联调。但是在用 Flutter 做应用开发时 Charles 却抓不到接口,到底是怎么回事呢 ?

尝试用其它客户端应用请求网络接口,Charles 都是可以成功抓取的,只有 Flutter 应用的接口无法抓到,到底是怎么回事呢 ?

经过一系列调研,发现 Flutter 应用的网络请求是不走手机的系统代理的,也就是说你在系统设置中设置了代理地址和端口号后 Flutter 也不会走你的代理,而抓接口是必须要设置代理的。如果不能走系统代理,那我们只有在代码中动态设置代理来解决问题了。

2.解决办法

设置http代理:DefaultHttpClientAdapter 提供了一个onHttpClientCreate 回调来设置底层 HttpClient的代理,我们想使用代理,可以参考下面代码 dio


  import 'dart:io'; 
  import 'package:dio/adapter.dart'; 
  import 'package:dio/dio.dart'; 
  
        floatingActionButton: new FloatingActionButton(
        onPressed: () async {
          // 添加这部分代码
          var dio = Dio();

          // 在调试模式下需要抓包调试,所以我们使用代理,并禁用HTTPS证书校验
          (dio.httpClientAdapter as DefaultHttpClientAdapter)
              .onHttpClientCreate = (client) {
            client.findProxy = (url) {
              return 'PROXY 172.25.84.99:8888'; //这里将localhost设置为自己电脑的IP,其他不变,注意上线的时候一定记得把代理去掉
            };
            //代理工具会提供一个抓包的自签名证书,会通不过证书校验,所以我们禁用证书校验
            client.badCertificateCallback =
                (X509Certificate cert, String host, int port) => true;
          };

          final response = await dio.get(
              'http://app.gjzwfw.gov.cn/fwmhapp1/code/getverifyCode.do?number=12345678');
          print('${response.data}');
        },
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),

http

  import 'dart:convert';
  import 'dart:io';
  import 'package:dio/dio.dart';
  floatingActionButton: new FloatingActionButton(
        onPressed: () async {
          var httpClient = new HttpClient();
          httpClient.findProxy = (url) {
            return HttpClient.findProxyFromEnvironment(url, environment: {
              "http_proxy": 'http://172.25.84.99:8888',
            });
          };

          var uri = new Uri.http(
              't.weather.sojson.com', '/api/weather/city/101210101');
          var request = await httpClient.getUrl(uri);
          var response = await request.close();
          if (response.statusCode == 200) {
            print('请求成功');
            var responseBody = await response.transform(Utf8Decoder()).join();
            print('responseBody = $responseBody');
          } else {
            print('请求失败');
          }
        },
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),

大功告成,然后就可以在flutter应用中对手机进行抓包啦~下面是我成功抓包的记录:

image.png