Flutter应用如何捕获网站加载过程中发起的全部网络请求
Flutter 实现网站全量加载请求捕获方案
要实现类似Chrome开发者工具的全量请求捕获能力,首先要注意:单纯使用dio、http等通用HTTP客户端仅能获取初始HTML响应,无法拿到页面渲染过程中JS发起的异步请求、静态资源加载请求,必须依赖WebView的渲染能力实现,常用落地方案如下:
方案1:可见WebView实现(适合需同时展示页面的场景)
使用官方维护的webview_flutter插件,通过资源拦截回调收集所有请求:
- 第一步安装依赖:执行命令
flutter pub add webview_flutter - 配置WebView的资源拦截回调,示例代码如下:
import 'package:webview_flutter/webview_flutter.dart'; final controller = WebViewController() ..setNavigationDelegate(NavigationDelegate( onPageStarted: (url) { // 页面开始加载时清空历史请求列表 requestList.clear(); }, onWebResourceError: (error) { // 可收集异常请求信息 }, )) ..loadRequest(Uri.parse('目标网站地址')); // 低版本webview_flutter可搭配webview_flutter_platform_interface扩展请求拦截能力
方案2:无头WebView实现(适合后台静默收集请求,无需展示页面的场景)
使用flutter_inappwebview插件提供的无头WebView能力,后台加载页面的同时收集全量请求,不会显示UI:
- 第一步安装依赖:执行命令
flutter pub add flutter_inappwebview - 配置无头WebView的资源加载回调,示例代码如下:
import 'package:flutter_inappwebview/flutter_inappwebview.dart'; List<LoadedResource> allRequests = []; final headlessWebView = HeadlessInAppWebView( initialUrlRequest: URLRequest(url: WebUri('目标网站地址')), onLoadResource: (controller, resource) { // 每触发一个资源请求都会回调,可拿到完整的请求、响应信息 allRequests.add(resource); debugPrint('捕获请求:${resource.url},状态码:${resource.response?.statusCode}'); }, onLoadStop: (controller, url) { // 页面加载完成后allRequests中存储了全部请求数据,可按需处理 debugPrint('全量请求收集完成,共${allRequests.length}条请求'); }, ); // 启动无头WebView开始加载和收集 headlessWebView.run();
轻量替代方案(仅能收集静态资源请求,无法获取JS动态请求)
如果不需要收集JS发起的异步接口请求,仅需要获取页面静态资源(图片、CSS、静态JS等),可直接用html解析库解析初始HTML的标签提取资源链接:
- 安装依赖:执行命令
flutter pub add html http - 示例代码如下:
import 'package:http/http.dart' as http; import 'package:html/parser.dart' as parser; Future<void> getStaticResources(String url) async { final response = await http.get(Uri.parse(url)); final document = parser.parse(response.body); // 提取图片链接 final imgs = document.getElementsByTagName('img').map((e) => e.attributes['src']); // 提取CSS链接 final css = document.getElementsByTagName('link').map((e) => e.attributes['href']); // 提取JS链接 final js = document.getElementsByTagName('script').map((e) => e.attributes['src']); // 合并所有资源链接即可 }
注意事项
- Android端需在
android/app/src/main/AndroidManifest.xml中配置网络权限,若需要访问HTTP站点需额外配置android:usesCleartextTraffic="true" - iOS端若需要访问HTTP站点需在
Info.plist中配置NSAppTransportSecurity相关规则,允许非HTTPS请求 - 捕获响应体时注意大文件资源的处理,避免内存溢出

内容的提问来源于stack exchange,提问作者TheShalty
相关产品推荐
相关产品推荐

