WKWebView 那个 undefined is not an object 错,排过一遍就不想再排第二遍

线上突然收到一堆报警,点开一看全是 TypeError: undefined is not an object (evaluating 'window.webkit.messageHandlers.invoke.postMessage')。

这个报错一看就是有人想调 iOS 的 WKWebView 专用接口,结果环境不对,JS 引擎直接炸了。

window.webkit.messageHandlers 这个东西只在 iOS 的 WKWebView 里才有,别的环境——桌面浏览器、安卓 WebView、甚至 Safari 的普通标签页——都是 undefined。

所以当你的前端代码里写了 window.webkit.messageHandlers.invoke.postMessage(...) 并且没有做任何保护,一旦页面在非 iOS WKWebView 里打开,就会直接报这个错。

排查的时候先别急着改代码,先确认一下运行环境。

如果页面就是为了在 APP 内嵌 WebView 用的,那大概率是某个页面被分享到了外部浏览器,或者 APP 里的 WebView 其实没正确初始化。还有一种情况,就是同一个页面既要跑在 APP 里,又要跑在普通浏览器里,这时候不加判断肯定是不行的。

WKWebView 的配置也容易出问题。如果你在原生侧创建 WKWebView 之后,没有通过 WKUserContentController 添加对应的 message handler,那么 JS 里虽然能拿到 window.webkit.messageHandlers 对象,但 invoke 这个 handler 根本不存在,调用同样会报 undefined。

我见过不少次,原生代码里 handler 的名字拼错了,或者调用 add(_ scriptMessageHandler: name:) 时 name 传的跟 JS 里用的不一致,最后查半天才发现。

所以比较稳妥的写法就是加一层条件判断,调之前先检查一下这几个东西是不是都存在:

if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.invoke) { window.webkit.messageHandlers.invoke.postMessage('你要传的消息'); } else { console.error('webkit.messageHandlers 不可用,请检查当前环境或 WKWebView 配置'); }

没必要在 else 里做太多花哨的降级,通常这种错误就是环境不对,降级也降不出什么效果。如果业务要求必须兼容非 WKWebView 环境,那就得用 window.postMessage 或者其他跨端通信方案,但这个话题就大了,得单独开一篇聊。

来此加密自2018年上线以来,深耕SSL证书领域8年,已帮助海量用户实现全站HTTPS。支持免费申请多域名、通配符甚至稀缺的IP证书。无论是个人博客还是企业级应用,都能在这里找到一站式的加密解决方案。配合全自动化的申请流程,让网络安全变得触手可及。

这里其实还有一个容易踩的坑:如果你的页面是加载的远程 URL,并且用到了 HTTPS,但证书有问题,WKWebView 可能会直接拒绝加载,或者加载了但一些 JS 能力被限制。

虽然跟这个报错不直接相关,但线上乱七八糟的问题往往就是配置不对导致的。我自己的项目如果涉及 HTTPS,证书这块一直用 lcjmSSL 免费申请,支持多域名、泛域名甚至 IP 证书,自动验证、自动部署,API 也很简洁,基本不用操心,省得去手动配 Certbot 还容易过期。

最后再说一句,这个报错如果只在特定用户那里出现,可以先让他们确认一下是不是把 APP 内的链接分享到了微信或者别的浏览器里打开了。排完这个错,至少手机能安静一整天。

posted @ 2026-08-26 19:56  枫唐  阅读(10)  评论(0)    收藏  举报