WKWebView捕获JS Error

本文探讨了WebView中JavaScript错误的捕获与处理方法,包括try-catch、window.onerror监听,以及如何将异常信息从JS传递给原生代码,介绍了两种主要的WebView和JS通信方式。

WebView里面会经常发生JSError,但是很多开发者却并未考虑过收集 JavaScript 出错时抛出的异常信息。因为只要 JavaScript 异常后 App 不会崩溃,当没有发生过就好了。
或许,在浏览器时代,让用户刷新下页面,可以解决异常问题。但是在移动 App 的 H5 页面,一但出现异常将导致程序无法正常运行,用户也不是那么容易可以通过刷新来解决问题的。

  • try-catch 主动 catch 异常处理或上报
try {   
    function();
} catch(e) {   
    console.log(e); 
    // report error maybe
}
  • window.onerror 监听错误事件捕获未处理的异常:
window.onerror = function (errorMsg, url, lineNumber) {  
    console.log('Error: ' + errorMsg + ' Script: ' + url + ' Line: ' + lineNumber);   
    // report error maybe
}

通过window.onerror捕获到异常后,js需要将信息传递到oc,那怎么传递呢?

WebView和JS通信一般有两种方式

  • 第一种就是 WebViewJavascriptBridge 实现的方式,是通过在 js 新建一个 iframe,iframe 指定一个自定义 scheme 的 url,将该 frame 添加到当前 dom 中。那么就可以分别通过 WKWebView 的
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)

以及UIWebView的

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool

拦截到该 iframe 的 url,根据 url 的 scheme 再做具体操作,这样就可以进行通信了,具体实现可以看 WebViewJavascriptBridge 的源码。这种方式的好处就是同时适用 UIWebView、WKWebView,项目中若是想要同时兼容这两个 WebView,使用这种方式比较方便。

  • 使用iOS提供的通信api

第二种是直接通过原生 API 进行通信,UIWebView 通过 JSContext,WKWebView 通过 WKScriptMessageHandler。注意 UIWebView 通过 JSContext 进行 JS 通信涉及到私有 API。

参考文章:

1、https://cloud.tencent.com/developer/article/1071030
2、https://cloud.tencent.com/developer/ask/68434
3、https://www.jianshu.com/p/642d5fd332db

### iOS18 中 WKWebView 加载 HTML 出现白屏的解决方案 在 iOS18 的环境中,WKWebView 可能由于多种原因导致加载 HTML 页面时出现白屏的情况。以下是针对该问题可能的原因分析以及对应的解决方案。 #### 1. **监听 `webViewWebContentProcessDidTerminate` 方法** 当 WKWebView 的 Web Content Process 被终止时,可能会触发白屏现象。此时可以重写 `webViewWebContentProcessDidTerminate:` 方法并重新加载页面: ```objective-c - (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView { [webView reload]; } ``` 这种方法适用于因内存不足或其他异常情况导致的 Web Content Process 终止场景[^2]。 --- #### 2. **监控 webView 的 title 属性变化** 部分情况下,WKWebView 白屏的同时其 `title` 属性会被清空。因此可以通过 KVO 或者其他方式监听 `title` 属性的变化来检测白屏状态,并采取相应措施: ```objective-c [self.webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:nil]; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { if ([keyPath isEqualToString:@"title"] && (!self.webView.title || self.webView.title.length == 0)) { NSLog(@"Detected blank screen, reloading..."); [self.webView reload]; } } ``` 此方法能够有效应对某些特定类型的白屏问题[^3]。 --- #### 3. **利用 WKNavigationDelegate 协议跟踪加载过程** 通过实现 `WKNavigationDelegate` 协议中的方法,可以更全面地了解页面加载的状态。特别是以下两个方法可以帮助捕获加载失败的信息: ```objective-c - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error { NSLog(@"Failed to load page provisionally: %@", error.localizedDescription); } - (void)webView:(WKWebView *)webView didFailNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error { NSLog(@"Failed to load page completely: %@", error.localizedDescription); } ``` 如果发现错误码为 `-1004`(网络连接中断)或者 `-999`(请求取消),可以根据具体需求决定是否尝试重新加载页面[^5]。 --- #### 4. **检查 Cordova 插件配置** 如果你的应用基于 Apache Cordova 构建,则需要确认插件路径是否正确设置。此外,在启用 WKWebView 支持后,需调整应用支持的最低 iOS 版本至 9+,否则可能导致兼容性问题引发白屏: ```javascript // 修改 cordova_plugins.js 文件中各插件路径 { "file": "../path/to/plugin/file", ... } ``` 同时更新项目的部署目标版本号: ```xml <!-- 在 config.xml 中 --> <preference name="deployment-target" value="9.0"/> ``` 这些改动有助于减少由插件引起的潜在冲突[^4]。 --- #### 5. **优化资源加载逻辑** 对于动态生成的内容或外部依赖较多的网页,建议预加载必要的 CSS 和 JavaScript 文件;另外还可以考虑引入缓存机制以提高性能稳定性。例如使用 Service Worker 缓存静态资产或将重要数据存储到本地数据库 SQLite/LiteDB 等位置供离线访问。 --- #### 总结 综合以上策略可极大程度降低 iOS18 下 WKWebView 遇见白屏的概率。实际开发过程中应结合具体情况逐一排查根本原因再施加针对性修复手段。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值