DingMing

丁大铭的个人空间,用来分享一些前端小技巧,默默成长吧,哈哈

JS与native交互方式

  |  
 阅读次数

原生和H5 的交互方式

在 原生开发 Hybrid App 的时候,前端和原生通信,需要jsBridge进行交互,在此总结下和原生一些交互的方式

需要说明App内嵌的H5都是基于原生WebView来实现的,为h5展示提供了容器

JS && OC

ios的WebView有两种,分别 是UIWebView 、WKWebView

  • UIWebView 比较老,但是银行页面必须使用这个
  • WKWebView 轻量级的新

UIWebView原生的交互原理

  1. 通过一个 JSContext 获取 UIWebView 的 JS 执行上下文,然后通过这个上下文,进行 OC & JS 的双端交互。
  2. 使用WebViewJavascriptBridge插件与JS交互
  3. 拦截http 请求截取参数进行交互(OC无法主动触发JS)

WebViewJavascriptBridge(IOS)原理与使用

原理

初始化时,创建一个iframe标签,src为https://__bridge_loaded__,OC截取这个url后,删除本地iframe并给html再次生成一个iframe,src是OC赋予的,并以这个url进行交互

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 初始化函数
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
window.WVJBCallbacks = [callback];
const WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(() => { document.documentElement.removeChild(WVJBIframe); }, 0);
}
// 触发函数
setupWebViewJavascriptBridge(() => {
});

// 使用方法
window.WebViewJavascriptBridge.callHandler(
'userInfo', // 方法名
{ param: '中文测试' }, // 参数
(responseData) => { // 回调
alert(responseData);
},
);

WKWebView原生的交互原理

通过 userContentController 把需要观察的 JS 执行函数注册起来。
然后通过一个协议方法,将所有注册过的 JS 函数执行的参数传递到此协议方法中。

JS To OC

这个方式是最通用方式

1
2
3
4
window.webkit.messageHandlers.userInfo.postMessage({name : "李四",age : 22});

userInfo // 方法名
{name : "李四",age : 22} // 参数

OC To JS

1
2
// js 在window下注册一个回调
// OC 触发 window下的这个回调 来进行交互

JS && Android

Android 4.0-4.4 没有jsBridge,可以使用url拦截传参

!!! 安卓传参只能接收字符串 需要进行转换

通信方式有两种:原生交互和插件WebViewJavascriptBridge

原生交互

1
2
3
window.AndroidWebView.userInfo({name : "李四",age : 22});
userInfo // 方法名
{name : "李四",age : 22} // 参数

WebViewJavascriptBridge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 初始化函数
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge);
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady',
() => {
callback(WebViewJavascriptBridge);
},
false,
);
}
}
// 触发
connectWebViewJavascriptBridge((bridge) => {
bridge.init((message, responseCallback) => {
console.log('JS got a message', message);
const data = {
'Javascript Responds': '测试中文!',
};
if (responseCallback) {
console.log('JS responding with', data);
responseCallback(data);
}
});
});

// 使用方法
window.WebViewJavascriptBridge.callHandler(
'userInfo', // 方法名
{ param: '中文测试' }, // 参数
(responseData) => { // 回调
alert(responseData);
},
);