问题详情: flutter 组件未进行特殊设置的情况下不会走代理,无法被抓包;
解决方案:
(1)在 dio
网络请求组件中设置代理的 ip
地址和 port
,强制使用代理请求网络;
class ProxyUtils {
// 是否启用代理
static bool PROXY_ENABLE = false;
/// 代理服务IP
static String PROXY_IP = '172.0.0.1';
/// 代理服务端口
static int PROXY_PORT = 8888;
}
// 在调试模式下需要抓包调试,所以我们使用代理,并禁用HTTPS证书校验
if (ProxyUtils.PROXY_ENABLE) {
(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
(client) {
client.findProxy = (uri) {
var ip = ProxyUtils.PROXY_IP;
var port = ProxyUtils.PROXY_PORT;
return "PROXY $ip:$port";
};
// 代理工具会提供一个抓包的自签名证书,会通不过证书校验,所以我们禁用证书校验
client.badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
};
}
(2)ip
和 port
肯定不能通过硬编码的方式写在代码中,所以我们通过路由传值的方式将 port
和 ip
从原生传到 flutter
组件;
获取当前代理 ip
和 port
(iOS):
// 自动获取手机代理
NSString *portalBaseUrlStr = @"http://www.baidu.com";
NSDictionary *proxySettings = (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:portalBaseUrlStr]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));
NSDictionary *settings = [proxies firstObject];
NSString *hostName = [NSString stringWithFormat:@"%@",settings[@"kCFProxyHostNameKey"]];
NSString *portName = [NSString stringWithFormat:@"%@",settings[@"kCFProxyPortNumberKey"]];
// 获取为空时居然是字符串"(null)"
if ([hostName isEqualToString:@"(null)"]) {
hostName = @"";
}
if ([portName isEqualToString:@"(null)"]) {
portName = @"";
}
NSString *proxy_ip = hostName;
NSString *proxy_port = portName;
通过路由传递 ip 和 port(iOS):
FlutterEngine *flutterEngine = [[FlutterEngine alloc] initWithName:@"io.flutter" project:nil];
if ([SystemInfoUtils isProxy]) {
NSString *route = [NSString stringWithFormat:@"wallpaper?port=%@&ip=%@", [SystemInfoUtils proxy_port],[SystemInfoUtils proxy_ip]];
[self.flutterEngine runWithEntrypoint:nil initialRoute:route];
} else {
[self.flutterEngine runWithEntrypoint:nil];
}
flutter 接收 ip
和 port
参数:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter',
theme: ThemeData(
primarySwatch: Colors.blue,
primaryColor: Colors.white,
),
home: _route(window.defaultRouteName),
builder: EasyLoading.init(),
);
}
}
Widget _route(String url) {
// 解析路由参数
Uri u = Uri.parse(url);
Map<String, String> qp = u.queryParameters;
final port = qp["port"];
final ip = qp["ip"];
if (port != null && ip != null) {
ProxyUtils.PROXY_ENABLE = true;
ProxyUtils.PROXY_IP = ip;
ProxyUtils.PROXY_PORT = int.parse(port);
print("Flutter config proxy ip is $ip port is $port");
}
//跳转页面
switch (u.path) {
case 'wallpaper':
return WallpaperViewController();
default:
return WallpaperViewController();
}
}
网友评论