You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 03:21:31