Flutter 做應用開發時 Charles 抓不到介面的解決辦法

fanyee^_^發表於2021-08-23

這是我參與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();

          (dio.httpClientAdapter as DefaultHttpClientAdapter)
              .onHttpClientCreate = (client) {
            client.badCertificateCallback =
                (X509Certificate cert, String host, int port) {
              return Platform.isAndroid;
            };
            client.findProxy = (url) {
              return 'PROXY 172.25.84.99:8888'; //這裡將localhost設定為自己電腦的IP,其他不變,注意上線的時候一定記得把代理去掉
            };
          };
      //程式碼截止

          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

相關文章