这是我参与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应用中对手机进行抓包啦~下面是我成功抓包的记录: