Flutter中如何通过InAppWebView监听网页后台请求?
解决方案
1. 拦截所有网络请求(含AJAX/Fetch)
利用flutter_inappwebview的shouldInterceptRequest回调捕获WebView发起的所有网络请求,包括页面刷新、资源加载及后台AJAX/Fetch请求,通过统计请求的启停状态控制原生加载器的显示:
- 维护一个请求计数器,捕获到请求时+1,请求完成/失败时-1
- 计数器>0时显示加载器,计数器归0时隐藏
示例代码:
int _activeRequests = 0; bool _isLoaderVisible = false; InAppWebView( initialUrlRequest: URLRequest(url: Uri.parse("你的网页地址")), shouldInterceptRequest: (controller, request) async { setState(() { _activeRequests++; if (!_isLoaderVisible) { _isLoaderVisible = true; } }); // 不拦截请求,允许正常发起 return null; }, onLoadResource: (controller, resource) async { setState(() { _activeRequests--; if (_activeRequests <= 0) { _activeRequests = 0; _isLoaderVisible = false; } }); }, onLoadError: (controller, url, code, message) { setState(() { _activeRequests--; if (_activeRequests <= 0) { _activeRequests = 0; _isLoaderVisible = false; } }); }, onLoadStop: (controller, url) { setState(() { _activeRequests = 0; _isLoaderVisible = false; }); }, )
若只需监听数据接口请求,可通过request.url过滤:
if (request.url.toString().contains("/api/")) { setState(() { _activeRequests++; _isLoaderVisible = true; }); }
2. 注入JavaScript监听AJAX/Fetch
若请求拦截无法覆盖特殊场景,可注入JS代码监听网页内的XMLHttpRequest和fetch调用,通过Flutter与JS的通信同步加载器状态:
步骤1:注入监听JS代码
onWebViewCreated: (controller) async { await controller.injectScript(source: """ // 监听XMLHttpRequest const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { window.flutter_inappwebview.callHandler('requestStart', url); this.addEventListener('loadend', function() { window.flutter_inappwebview.callHandler('requestEnd', url); }); return originalOpen.apply(this, arguments); }; // 监听fetch const originalFetch = window.fetch; window.fetch = function(resource) { window.flutter_inappwebview.callHandler('requestStart', resource); return originalFetch.apply(this, arguments).then(response => { window.flutter_inappwebview.callHandler('requestEnd', resource); return response; }).catch(error => { window.flutter_inappwebview.callHandler('requestEnd', resource); throw error; }); }; """); },
步骤2:Flutter端接收JS回调
onWebViewCreated: (controller) async { // 注入JS代码... controller.addJavaScriptHandler( handlerName: 'requestStart', callback: (args) { setState(() { _activeRequests++; _isLoaderVisible = true; }); }, ); controller.addJavaScriptHandler( handlerName: 'requestEnd', callback: (args) { setState(() { _activeRequests--; if (_activeRequests <= 0) { _activeRequests = 0; _isLoaderVisible = false; } }); }, ); },
这种方式可精准监听数据请求,避免静态资源干扰。
3. 组合两种方法提升可靠性
若单一方法存在遗漏,可同时启用请求拦截与JS注入,确保所有后台请求都被捕获,避免加载器状态异常。
内容的提问来源于stack exchange,提问作者Enrique Martinez Parra
相关产品推荐
相关产品推荐

