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

iOS Flutter WebView注入JS触发FWFEvaluateJavaScriptError异常求助

问题排查与解决方案

1. 解决重复注入JS引发的冲突

你的代码在onPageFinished中每次页面加载完成都注入监听JS,会导致多次覆盖history.pushState、重复绑定popstate事件,引发JS上下文冲突,触发执行错误。

给JS添加执行标记,避免重复注入:

final pushStateSpyJavaScript = '''
if (!window.__pushStateSpyInjected) {
  window.__pushStateSpyInjected = true;
  ((history)=>{
    const org=history.pushState;
    history.pushState=(state,_,url)=>{
      org.apply(history, [state,_,url]);
      if(url) {
        window.flutter.postMessage(url.toString());
      }
    };
    addEventListener('popstate', (event) => window.flutter.postMessage(location.href.toString()));
  })(window.history);
}
''';

2. 处理window.flutter未就绪的情况

页面刚加载完成时,Flutter的JavaScriptChannel可能还未初始化,直接调用window.flutter.postMessage会触发JS报错,进而抛出PlatformException。

给postMessage添加安全判断:

final pushStateSpyJavaScript = '''
if (!window.__pushStateSpyInjected) {
  window.__pushStateSpyInjected = true;
  ((history)=>{
    const org=history.pushState;
    history.pushState=(state,_,url)=>{
      org.apply(history, [state,_,url]);
      if(url && window.flutter?.postMessage) {
        window.flutter.postMessage(url.toString());
      }
    };
    addEventListener('popstate', (event) => {
      if (window.flutter?.postMessage) {
        window.flutter.postMessage(location.href.toString());
      }
    });
  })(window.history);
}
''';

也可以延迟注入JS,给Channel初始化留时间:

onPageFinished: (url) {
  onUrlChanged(url);
  Future.delayed(const Duration(milliseconds: 300), () {
    webViewController.runJavaScript(pushStateSpyJavaScript);
  });
},

3. 获取JS执行的具体错误信息

用runJavaScriptReturningResult替代runJavaScript,能捕获更详细的JS错误,帮助定位问题:

onPageFinished: (url) {
  onUrlChanged(url);
  webViewController.runJavaScriptReturningResult(pushStateSpyJavaScript)
    .catchError((error) {
      print('JS执行错误详情: $error');
    });
},

4. 确认WebView开启JS支持

检查WebView配置是否开启了JavaScript,否则注入的JS无法执行:

final webViewController = WebViewController()
  ..setJavaScriptMode(JavaScriptMode.unrestricted) // 必须开启
  ..addJavaScriptChannel('flutter', onMessageReceived: (message) {
    onUrlChanged(message.message);
  });

5. 限制JS仅在主窗口执行

如果页面包含iframe,注入的JS会在iframe中执行,但iframe中不存在window.flutter,会引发错误。添加主窗口判断:

final pushStateSpyJavaScript = '''
if (window.top === window && !window.__pushStateSpyInjected) {
  window.__pushStateSpyInjected = true;
  // 原有监听代码
}
''';

内容的提问来源于stack exchange,提问作者rekire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:07:41