flutter_inappwebview 6.1.0加载React页面外部JS脚本失败(仅部分用户出现空白屏问题)
看起来这个问题确实挺头疼的——只在小部分无规律的设备上发作,既没有明显报错也找不到统一触发条件。结合你描述的场景和已经排查过的点,我整理了几个方向,你可以逐一尝试:
1. 先抓WebView的隐藏错误日志
你提到try-catch里的alert没触发,但很多WebView会把脚本错误、加载异常隐藏在控制台里,不会主动弹出提示。建议先给Flutter的WebView加上日志监听,把这些隐藏的错误挖出来:
InAppWebView( // 保留原有配置... onConsoleMessage: (controller, consoleMessage) { print('WebView 控制台日志: ${consoleMessage.message} (级别: ${consoleMessage.level.name})'); }, onLoadError: (controller, url, code, message) { print('WebView 加载错误: $code - $message'); }, onHttpError: (controller, request, errorResponse) { print('WebView HTTP错误: ${errorResponse.statusCode} - ${errorResponse.reasonPhrase}'); }, )
这些监听能帮你抓到WebView本身的加载异常、脚本执行错误,哪怕没有alert提示。
2. 动态脚本注入被WebView安全策略拦截
部分设备的WebView可能因为系统安全设置、厂商定制的内核差异(比如部分安卓机型的定制WebView、iOS旧版WebKit),默认开启了严格的内容安全策略(CSP),直接拦截了动态创建的<script>标签,而且不会抛出可见错误。
排查&解决:
- 先检查React页面的响应头里有没有
Content-Security-Policy,部分设备对CSP规则的解析更严格,比如不允许blob:协议的脚本,或者限制了同域脚本的加载方式。 - 可以尝试绕过动态脚本标签的限制:把脚本内容通过Flutter主动加载并注入,而不是让React页面自己请求:
- 在Flutter里用Dio/HttpClient直接请求Spring API拿到JS字符串;
- 然后通过
evaluateJavascript直接执行脚本内容:// 自己实现的API请求逻辑 String jsContent = await _fetchJsFromSpringApi(); await _webViewController?.evaluateJavascript(source: jsContent);
3. Blob URL的兼容性问题
你提到用axios请求Blob后生成URL给脚本标签,部分设备的WebView对Blob URL的脚本加载支持有问题——比如安卓14的WebView对Blob资源的权限控制更严格,或者部分iOS设备的WebKit不允许从Blob URL执行脚本。
排查&解决:
- 暂时跳过Blob中转,直接让
<script>标签请求API的原始URL:
如果这样能解决问题,基本可以确定是Blob URL的兼容性问题。// 替换原来的axios+Blob逻辑 try { const script = document.createElement('script'); script.src = '/down?formPath=/resources/example/form-ex.js'; script.defer = true; script.onload = () => window.flutter_inappwebview.callHandler('formRendered'); script.onerror = (err) => alert('脚本加载失败: ' + err.message); document.body.appendChild(script); } catch (e) { alert('脚本注入错误: ' + e); }
4. WebView缓存导致的无效资源加载
少数用户的WebView可能缓存了无效的空资源,或者缓存策略导致脚本请求被直接跳过。可以尝试强制禁用WebView缓存:
initialSettings: InAppWebViewSettings( cacheEnabled: false, javaScriptEnabled: true, ),
另外,给API请求加个时间戳参数避免缓存命中:
script.src = `/down?formPath=/resources/example/form-ex.js&t=${Date.now()}`;
5. 网络环境的隐形拦截
部分用户可能连接了企业VPN、校园网或者第三方代理,这些网络会静默拦截特定请求(比如Blob URL、同域脚本请求),但不会返回错误提示。建议让出现问题的用户切换到手机热点或者其他网络测试,如果问题消失,就说明是网络环境导致的。
总结
因为问题只在小部分设备上出现,最关键的是先通过WebView的控制台监听抓到隐藏的错误日志,定位具体原因。如果暂时抓不到日志,可以先尝试改变脚本加载方式(绕过Blob、直接通过Flutter注入脚本),看看能否绕过兼容性问题。
内容来源于stack exchange

