messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + ‘😕/’ + event;
document.documentElement.appendChild(messagingIframe);
setTimeout(() => {
document.documentElement.removeChild(messagingIframe);
}, 200)
}
拦截式在双端都具有非常好的向下兼容性,曾经是最主流的 JSB 实现方案,但目前在高版本的系统中已经逐渐被淘汰,理由是它有如下几个劣势:
-
连续发送时可能会造成消息丢失(可以使用消息队列解决该问题)
-
URL 字符串长度有限制
-
性能一般,URL request 创建请求有一定的耗时(Android 端 200-400ms)
实践案例
同样用一个简单的 Demo2 来看一下如何使用拦截式实现 Web 向 Native 发送消息,这里实现了在 Web 端唤起 Native 的相册。
遵循上述实现方式,Web 发送消息的代码如下:
const CUSTOM_PROTOCOL_SCHEME = ‘prek’ // 自定义 url scheme
function web2Native(event_name) {
const messagingIframe = document.createElement(‘iframe’)
messagingIframe.style.display = ‘none’
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + ‘😕/’ + event_name
document.documentElement.appendChild(messagingIframe)
setTimeout(() => {
document.documentElement.removeChild(messagingIframe)
}, 0)
}
const btn = document.querySelector(‘#btn’)
btn.onclick = () => {
web2Native(‘openPhotoAlbum’)
}
Native 侧通过 decidePolicyForNavigationAction
这一 delegate 实现请求拦截,解析 URL 参数,若 URL scheme 是 prek
则认为该请求是一个来自 Web 的 JSB 调用:
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *url = navigationAction.request.URL;
NSLog(@