We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在开发 web App 的时候,我们会用 JSBridge 来调用 Native 的一些功能,作为一名前端开发,JSBridge 实现这块不一定是我们开发的,但也要对 JSBridge 实现原理做到了解。
h5 和 native 约定一个通信协议,例如 jsbridge, 同时约定调用 native 的方法名作为域名,以及带上参数 和 接收方法执行结果的 js 方法名 cbName,例如
"jsbridge://openScan?{"data": {"scanType": "qrCode"}, "cbName": "handleScanResult"}"
因为它 支持 iOS6,所以为了实现兼容很多方案会使用这种方式。
window.location.href = "jsbridge://callNativeNslog?{"data": "111", "cbName": ""}"; window.location.href = "jsbridge://callNativeNslog?{"data": "222", "cbName": ""}";
js 此时的诉求是在同一个运行逻辑内,快速的连续发送出 2 个通信请求,用客户端本身 IDE 的 log,按顺序打印 111,222,那么实际结果是 222 的通信消息根本收不到,直接会被系统抛弃丢掉。
原因:因为 h5 的请求归根结底是一种模拟跳转,跳转这件事情上 webview 会有限制,当 h5 连续发送多条跳转的时候,webview 会直接过滤掉后发的跳转请求,因此第二个消息根本收不到。 2. URL 长度限制 如果需要传输的数据较长,例如方法参数很多时,由于 URL 长度限制,会丢失部分数据。 3. 耗时长 创建请求,需要一定的耗时,比注入 API 的方式调用同样的功能,耗时会较长。 4. web 环境报错 在浏览器环境下,会跳转到不存在的页面
因为 alert confirm 比较常用,所以一般通过 prompt 进行通信。
约定的传输数据的组合方式以及 js 端封装方法的可以类似上面的 拦截 URL Schema 提到的方式。
function callNative(methodName, arg, cb) { ... const url = 'jsbridge://' + method + '?' + JSON.stringify(args); prompt(url); }
native 会拦截 h5 发出的 prompt,当检测到协议为 jsbridge 而非普通的 http/https/file 等协议时,会拦截该请求,解析出 URL 中的 methodName、arg、 cbName,执行该方法并调用 js 回调函数。
没发现
即由 native 将实例对象通过 webview 提供的方法注入到 js 全局上下文,js 可以通过调用 native 的实例方法来进行通信。
具体有安卓 webview 的 addJavascriptInterface,iOS UIWebview(iOS2+) 的 JSContext,iOS WKWebview(iOS8+)的 scriptMessageHandler。
h5 端可以在 js 调用 window._jsbridge 实例下面的 call 方法,传入的数据组合方式可以类似上面两种方式。具体代码如下:
window.callbackId = 0; function callNative(method, arg, cb) { let args = { data: arg === undefined ? null : JSON.stringify(arg) }; if (typeof cb === 'function') { const cbName = 'CALLBACK' + window.callbackId++; window[cbName] = cb; args['cbName'] = cbName; } if (window._jsbridge) { window._jsbridge.call(method, JSON.stringify(args)); } }
官方提供,方便简捷
Native 注入的方法和时机都受限,JS 调用 Native 之前需要先判断 JSBridge 是否注入成功
在安卓 4.2 以下有安全漏洞,在 4.2 之前,Android 注入 JavaScript 对象的接口是 addJavascriptInterface,但是这个接口有漏洞,可以被不法分子利用,危害用户的安全,因此在 4.2 中引入新的接口 @JavascriptInterface(上面代码中使用的)来替代这个接口,解决安全问题。
Native 调用 JS 比较简单,只要 H5 将 JS 方法暴露在 Window 上给 Native 调用即可。
mWebview.loadUrl("javascript: func()");
mWebview.evaluateJavascript("javascript: func()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { return; } });
参考: https://segmentfault.com/a/1190000025182935 https://segmentfault.com/a/1190000021818496 https://juejin.cn/post/6844903936248250375#heading-2
The text was updated successfully, but these errors were encountered:
No branches or pull requests
在开发 web App 的时候,我们会用 JSBridge 来调用 Native 的一些功能,作为一名前端开发,JSBridge 实现这块不一定是我们开发的,但也要对 JSBridge 实现原理做到了解。
JS 调用 Native
1. 拦截 Url Schema(假请求)
2. 拦截 prompt alert confirm
3. 注入 JS 上下文
拦截 Url Schema(假请求)
h5 和 native 约定一个通信协议,例如 jsbridge, 同时约定调用 native 的方法名作为域名,以及带上参数 和 接收方法执行结果的 js 方法名 cbName,例如
优点:
因为它 支持 iOS6,所以为了实现兼容很多方案会使用这种方式。
缺点:
js 此时的诉求是在同一个运行逻辑内,快速的连续发送出 2 个通信请求,用客户端本身 IDE 的 log,按顺序打印 111,222,那么实际结果是 222 的通信消息根本收不到,直接会被系统抛弃丢掉。
原因:因为 h5 的请求归根结底是一种模拟跳转,跳转这件事情上 webview 会有限制,当 h5 连续发送多条跳转的时候,webview 会直接过滤掉后发的跳转请求,因此第二个消息根本收不到。
2. URL 长度限制
如果需要传输的数据较长,例如方法参数很多时,由于 URL 长度限制,会丢失部分数据。
3. 耗时长
创建请求,需要一定的耗时,比注入 API 的方式调用同样的功能,耗时会较长。
4. web 环境报错
在浏览器环境下,会跳转到不存在的页面
拦截 prompt alert confirm
因为 alert confirm 比较常用,所以一般通过 prompt 进行通信。
约定的传输数据的组合方式以及 js 端封装方法的可以类似上面的 拦截 URL Schema 提到的方式。
native 会拦截 h5 发出的 prompt,当检测到协议为 jsbridge 而非普通的 http/https/file 等协议时,会拦截该请求,解析出 URL 中的 methodName、arg、 cbName,执行该方法并调用 js 回调函数。
优点:
没发现
缺点:
注入 JS 上下文
即由 native 将实例对象通过 webview 提供的方法注入到 js 全局上下文,js 可以通过调用 native 的实例方法来进行通信。
具体有安卓 webview 的 addJavascriptInterface,iOS UIWebview(iOS2+) 的 JSContext,iOS WKWebview(iOS8+)的 scriptMessageHandler。
h5 端可以在 js 调用 window._jsbridge 实例下面的 call 方法,传入的数据组合方式可以类似上面两种方式。具体代码如下:
优点:
官方提供,方便简捷
缺点:
Native 注入的方法和时机都受限,JS 调用 Native 之前需要先判断 JSBridge 是否注入成功
在安卓 4.2 以下有安全漏洞,在 4.2 之前,Android 注入 JavaScript 对象的接口是 addJavascriptInterface,但是这个接口有漏洞,可以被不法分子利用,危害用户的安全,因此在 4.2 中引入新的接口 @JavascriptInterface(上面代码中使用的)来替代这个接口,解决安全问题。
Native 调用 JS
1. loadUrl
2. evaluateJavascript
loadUrl
Native 调用 JS 比较简单,只要 H5 将 JS 方法暴露在 Window 上给 Native 调用即可。
evaluateJavascript
参考:
https://segmentfault.com/a/1190000025182935
https://segmentfault.com/a/1190000021818496
https://juejin.cn/post/6844903936248250375#heading-2
The text was updated successfully, but these errors were encountered: