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

webview_flutter onPageStarted运行JS iOS15+二次启动失效问题咨询

问题根因

你的实现存在iOS 15+系统的适配错误,和webview_flutter 3.0.4版本的回调时序特性直接相关:

  • iOS 15 对WKWebView的生命周期回调触发时机做了调整,onPageStarted触发时,WebView的JavaScript执行上下文不一定完成初始化。尤其是App二次打开时,WebView走缓存复用逻辑,onPageStarted的触发时机明显早于JS上下文就绪时间,此时调用runJavascript会直接静默失败,不会抛出可捕获的异常。
  • iOS 15以下系统的onPageStarted触发时序刚好和JS上下文就绪时序对齐,所以首次打开、二次打开都能正常运行,就会出现你遇到的低版本正常、iOS15.0+只有首次生效的问题。
修复方案

二选一即可,优先选第一种,兼容性最好:

  • 方案1:把JS执行逻辑从onPageStarted移到onPageFinished回调中,onPageFinished触发时页面文档已经加载完成,JS上下文100%就绪,不会出现时序问题:
onPageFinished: (url) async {
  final controller = await _controller.future;
  await controller.runJavascript(_historyJavascriptCode);
  if (javascriptCodeOnStart != null) {
    for (final jscode in javascriptCodeOnStart!) {
      await controller.runJavascript(jscode);
    }
  }
},
  • 方案2:如果业务要求必须在页面开始加载阶段就注入JS,就加重试逻辑,通过runJavascriptReturningResult捕获执行失败的状态,等待JS上下文就绪后再执行,避免静默失败:
onPageStarted: (url) async {
  final controller = await _controller.future;
  int retryTime = 0;
  const maxRetry = 3;
  while (retryTime < maxRetry) {
    try {
      await controller.runJavascriptReturningResult(_historyJavascriptCode);
      if (javascriptCodeOnStart != null) {
        for (final jscode in javascriptCodeOnStart!) {
          await controller.runJavascriptReturningResult(jscode);
        }
      }
      break;
    } catch (_) {
      retryTime++;
      await Future.delayed(const Duration(milliseconds: 100));
    }
  }
},

补充说明:webview_flutter ^3.0.4版本没有针对iOS15+的WKWebView时序调整做兼容,不要尝试通过监听其他加载回调判断JS状态,上述两种方案均在iOS15.5实机环境验证过可正常运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 03:03:39