要描述什么是js Bridge,我们得先知道js Bridge是在什么地方去应用 什么是js Bridge呢
- js,或者H5中无法直接调用native API, native API是什么意思呢?就是手机里面的app
- 需要通过一些'特殊'的格式来调用
- 这些格式就统称为js Bridge, 例如微信JSSDK,微信JSSDK应该是我们用的最多的了
js Bridge常见实现方式
- 注册全局API
- 通过向window注册一些属性,如window.getVersion = xxx,这种方式比较适合比较简单的同步的方式,异步的方式比较适合 URL Scheme方式
- URL Scheme:自己造一个协议标准,让app去做一层拦截,不要发送网络请求
- 适合所有的情况
- 大家可以搜索 微信 scheme就可以找到很多资料,类似
weixin://dl/feedback的格式,如chrome://version 正常情况下,app里面的webview要请求接口,需要通过app再到网络去请求接口(http/https),数据返回回来后也要先经过app再到webview页面;那么URL Scheme,约定好前缀URL,比如my-app-name://api/getname,当app识别到my-app-diary,app就自己去处理并设置信息返回了,不需要通过接口了
封装js-bridge
const sdk = {
invoke(url, data = {}, onSuccess, onError){
const iframe = document.createElement('iframe')
iframe.style.visibility = 'hidden';
document.body.appendChild(iframe)
iframe.onload = () => {
const content = iframe.contentWindow.document.body.innerHTML;
onSuccess(JSON.parse(content))
iframe.remove()
}
iframe.onerror = () => {
onError()
iframe.remove()
}
iframe.src = `my-app-diary://${url}?data={JSON.stringify(data)}`
},
scan(data, onSuccess,onError){ // 扫一扫的功能
this.invoe('api/scan', data,onSuccess, onError )
}
}
// 使用
sdk.scan(data,onSuccess, onError )
在实际项目中,我们h5调用app的方法,项目用的是通过注入API的方式,如:
'use strict'
(function(){
function AppHelper() {}
function isMyApp() { // 判断是否自己的app标识
return navigator.userAgent.includes("myAppxxx");
}
AppHelper.prototype.setupWebViewJavascriptBridge = function (e) {
if (isMyApp()) {
if (window.WebViewJavascriptBridge) return e(WebViewJavascriptBridge);
if (window.WVJBCallbacks) return window.WVJBCallbacks.push(e);
window.WVJBCallbacks = [e];
var i = document.createElement("iframe");
i.style.display = "none";
i.src = "https://__bridge_loaded__";
document.documentElement.appendChild(i);
setTimeout(function () {
document.documentElement.removeChild(i);
}, 0);
}
};
// app暴露给h5端的方法:获取登录token
AppHelper.prototype.nativeToken = function () {
var res =
arguments.length > 0 && arguments[0] !== undefined
? arguments[0]
: function (res) {};
this.setupWebViewJavascriptBridge(function (bridge) {
bridge.callHandler("nativeToken", {}, res);
});
};
// app暴露给h5端的方法:app登录状态改变方法
AppHelper.prototype.loginStateChange = function (resFunc) {
this.setupWebViewJavascriptBridge(function (bridge) {
// loginStateChange需要跟app端的同学约定好
bridge.registerHandler("loginStateChange", function (
data,
responseCallback
) {
resFunc && resFunc(data);
});
});
};
window.AppHelper = new AppHelper()
}()
///=================h5端使用:====================
AppHelper.nativeToken((res)=> {
if(!!res){ // 可以拿到token, 说明登录成功
// do something...
}
})