一、什么是JSBridge


主要是给 JavaScript 提供调用 Native 功能的接口,让混合开发中的前端部分可以方便地使用 Native 的功能(例如:地址位置、摄像头)。
而且 JSBridge 的功能不止调用 Native 功能这么简单宽泛。实际上,JSBridge 就像其名称中的Bridge的意义一样,是 Native 和非 Native 之间的桥梁,它的核心是构建 Native 和非 Native 间消息通信的通道,而且这个通信的通道是双向的。

双向通信的通道:

  • JS 向 Native 发送消息: 调用相关功能、通知 Native 当前 JS 的相关状态等。
  • Native 向 JS 发送消息: 回溯调用结果、消息推送、通知 JS 当前 Native 的状态等。

H5与Native交互如下图:

二、JSBridge 的实现原理


JavaScript 是运行在一个单独的 JS Context 中(例如,WebView 的 Webkit 引擎、JSCore)。由于这些 Context 与原生运行环境的天然隔离,我们可以将这种情况与 RPC(Remote Procedure Call,远程过程调用)通信进行类比,将 Native 与 JavaScript 的每次互相调用看做一次 RPC 调用。

在 JSBridge 的设计中,可以把前端看做 RPC 的客户端,把 Native 端看做 RPC 的服务器端,从而 JSBridge 要实现的主要逻辑就出现了:通信调用(Native 与 JS 通信) 和句柄解析调用。

三、JSBridge 的通信原理


1.JavaScript 调用 Native的方式

主要有两种:注入API拦截URL SCHEME

1.1 注入API

注入 API 方式的主要原理是,通过 WebView 提供的接口,向 JavaScript 的 Context(window)中注入对象或者方法,让 JavaScript 调用时,直接执行相应的 Native 代码逻辑,达到 JavaScript 调用 Native 的目的。

对于 iOS 的 UIWebView,实例如下:

JSContext *context = [uiWebView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];context[@"postBridgeMessage"] = ^(NSArray<NSArray *> *calls) {// Native 逻辑
};//前端调用方式:
window.postBridgeMessage(message);

对于 iOS 的 WKWebView 可以用以下方式:

@interface WKWebVIewVC ()<WKScriptMessageHandler>@implementation WKWebVIewVC- (void)viewDidLoad {[super viewDidLoad];WKWebViewConfiguration* configuration = [[WKWebViewConfiguration alloc] init];configuration.userContentController = [[WKUserContentController alloc] init];WKUserContentController *userCC = configuration.userContentController;// 注入对象,前端调用其方法时,Native 可以捕获到[userCC addScriptMessageHandler:self name:@"nativeBridge"];WKWebView wkWebView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:configuration];// TODO 显示 WebView
}- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {if ([message.name isEqualToString:@"nativeBridge"]) {NSLog(@"前端传递的数据 %@: ",message.body);// Native 逻辑}
}// 前端调用方式:
window.webkit.messageHandlers.nativeBridge.postMessage(message);
1.2 拦截 URL SCHEME

解释一下 URL SCHEME:URL SCHEME 是一种类似于url的链接,是为了方便app直接互相调用设计的,形式和普通的 url 近似,主要区别是 protocol 和 host 一般是自定义的。

例如:
qunarhy://hy/url?url=ymfe.tech,
protocol 是 qunarhy,host 则是 hy。

拦截 URL SCHEME 的主要流程是:Web 端通过某种方式(例如 iframe.src)发送 URL Scheme 请求,之后 Native 拦截到请求并根据 URL SCHEME(包括所带的参数)进行相关操作。

在时间过程中,这种方式有一定的缺陷:

  • 使用 iframe.src 发送 URL SCHEME 会有 url 长度的隐患。

有些方案为了规避 url 长度隐患的缺陷,在 iOS 上采用了使用 Ajax 发送同域请求的方式,并将参数放到 head 或 body 里。这样,虽然规避了 url 长度的隐患,但是 WKWebView 并不支持这样的方式。

为什么选择 iframe.src 不选择 locaiton.href ?
因为如果通过 location.href 连续调用 Native,很容易丢失一些调用。

  • 创建请求,需要一定的耗时,比注入 API 的方式调用同样的功能,耗时会较长。

因此:JavaScript 调用 Native 推荐使用注入 API 的方式

2.Native 调用 JavaScript 的方式

相比于 JavaScript 调用 Native, Native 调用 JavaScript 较为简单,直接执行拼接好的 JavaScript 代码即可。

从外部调用 JavaScript 中的方法,因此 JavaScript 的方法必须在全局的 window 上。

对于 iOS 的 UIWebView,示例如下:

result = [uiWebview stringByEvaluatingJavaScriptFromString:javaScriptString];* javaScriptString为JavaScript 代码串

对于 iOS 的 WKWebView,示例如下:

[wkWebView evaluateJavaScript:javaScriptString completionHandler:completionHandler];

四、JSBridge 接口实现


从上面的剖析中,可以得知,JSBridge 的接口主要功能有两个:调用 Native(给 Native 发消息) 和 接被 Native 调用(接收 Native 消息)。因此,JSBridge 可以设计如下:

window.JSBridge = {// 调用 Nativeinvoke: function(msg) {// 判断环境,获取不同的 nativeBridgenativeBridge.postMessage(msg);},receiveMessage: function(msg) {// 处理 msg}
};

在上面部分中,提到过 RPC 中有一个非常重要的环节是 句柄解析调用 ,这点在 JSBridge 中体现为 句柄与功能对应关系。同时,我们将句柄抽象为 桥名(BridgeName),最终演化为一个 BridgeName 对应一个 Native 功能或者一类 Native 消息。基于此点,JSBridge 的实现可以优化为如下:

window.JSBridge = {// 调用 Nativeinvoke: function(bridgeName, data) {// 判断环境,获取不同的 nativeBridgenativeBridge.postMessage({bridgeName: bridgeName,data: data || {}});},receiveMessage: function(msg) {var bridgeName = msg.bridgeName,data = msg.data || {};// 具体逻辑}
};

终极提问:消息都是单向的,那么调用 Native 功能时 Callback 怎么实现的?

对于 JSBridge 的 Callback ,其实就是 RPC 框架的回调机制。当然也可以用更简单的 JSONP 机制解释:

当发送 JSONP 请求时,url 参数里会有 callback 参数,其值是 当前页面唯一 的,而同时以此参数值为 key 将回调函数存到 window 上,随后,服务器返回 script 中,也会以此参数值作为句柄,调用相应的回调函数。

整体流程

在 Native 端配合实现 JSBridge 的 JavaScript 调用 Native 逻辑也很简单,主要的代码逻辑是:接收到 JavaScript 消息 => 解析参数,拿到 bridgeName、data 和 callbackId => 根据 bridgeName 找到功能方法,以 data 为参数执行 => 执行返回值和 callbackId 一起回传前端

Native调用 JavaScript 也同样简单,直接自动生成一个唯一的 ResponseId,并存储句柄,然后和 data 一起发送给前端即可。

五、JSBridge 的引用


对于 JSBridge 的引用,常用有如下两种方式,但各有利弊。

1.由 Native 端进行注入

注入方式和 Native 调用 JavaScript 类似,直接执行桥的全部代码。

它的优点是:

桥的版本很容易与 Native 保持一致,Native 端不用对不同版本的 JSBridge 进行兼容。

它的缺点是:

注入时机不确定,需要实现注入失败后重试的机制,保证注入的成功率,同时 JavaScript 端在调用接口时,需要优先判断 JSBridge 是否已经注入成功。

2.由 JavaScript 端引用

直接与 JavaScript 一起执行。

它的优点是:

JavaScript 端可以确定 JSBridge 的存在,直接调用即可。

它的缺点是:

如果桥的实现方式有更改,JSBridge 需要兼容多版本的 Native Bridge 或者 Native Bridge 兼容多版本的 JSBridge。

JSBridge的原理及使用相关推荐

  1. jsbridge实现及原理_Android JSBridge的原理与实现

    原标题:Android JSBridge的原理与实现 JSBridge 在Android中,JSBridge已经不是什么新鲜的事物了,各家的实现方式也略有差异.大多数人都知道WebView存在一个漏洞 ...

  2. JSBridge的原理与实现

    为什么要用 JSBridge 顾名思义,JSBridge是js和Native之间通信的桥梁. Android4.2以下,addJavascriptInterface方式有安全漏洞. url schem ...

  3. JSBridge 技术原理分析

    -     JSBridge的起源    - PhoneGap(Codova 的前身)作为 Hybrid 鼻祖框架,是一个开源的移动开发框架,允许你用标准的web技术-HTML5,CSS3和JavaS ...

  4. JSBridge通信原理

    JSBridge是个啥 直接来重点,记住:JSBridge 是一个很简单的东西,更多的是一种形式.一种思想,为了解决 H5 和 Native 的双向通信. 就像我们刚接触 ajax 时,也很懵逼.其实 ...

  5. android 混编JsBridge的原理和实现

    首先我们先要知道 js调用Android的方法有以下四种: WebView的JavascriptInterface WebViewClient.shouldOverrideUrlLoading() W ...

  6. jsbridge实现及原理_JSBridge 实现原理解析

    JSBridge 项目以 js 与 android 通信为例,讲解 JSBridge 实现原理,下面提到的方法在 iOS(UIWebview 或 WKWebview)均有对应方法. 1. native ...

  7. 深入浅出JSBridge:从原理到使用

    一.前言 在如今移动端盛行的年代,技术选型上基本都是混合开发(Hybrid),混合开发是一种开发模式,指使用多种开发模型开发App,通常会涉及到两大类技术:原生Native.Web H5 原生技术主要 ...

  8. jsbridge实现及原理_jsBridge原理解析

    导语 现在大多数App与H5的交互越来越多,jsBridge是一个能使webView和js交互的通信方式,本文只对https://github.com/lzyzsd/JsBridge(以下涉及到的js ...

  9. jsbridge实现及原理_JsBridge使用和原理

    What is JsBridge 近期在做一个项目,使用的是Native+H5的方式实现的.众所周知的是在Android中,Webview所实现的java与js的交互存在一些安全问题,并且这样的使用方 ...

最新文章

  1. 倒计时一天 坚果智能影院让家用投影投出你的新生活主义
  2. LeetCode 7 反转整数
  3. linux系统中条码如何识别的,如何(可靠地)在嵌入式(无头)Linux中读取USB条形码扫描仪?...
  4. 全球及中国膀胱癌药物行业“十四五”专项规划及市场调研分析报告2021-2027年
  5. Ajax知识笔记——入门,同步和异步,XHR
  6. linux系统文件的复制,linux操作系统文件复制操作
  7. Linux系统性能查询命令
  8. 【软件工程】抽象泄漏
  9. 数据库——SQL-SERVER练习(4) 建表及数据完整性
  10. html 复选按钮(input checkbox)
  11. 计算机算法设计与分析 找零钱问题
  12. Debian 8 时间同步
  13. macOS下JetBrains配置修改错误导致无法启动解决方案
  14. pingback协议与traceback协议的区别
  15. 冒死揭开饭圈遮羞布,明星僵尸粉盘点
  16. linux find查找时间段文件,查找某个时间段的文件和find命令
  17. 使用软碟通安装win7
  18. 软件测试-web自动化测试教程
  19. 主成分分析法怎么提取图片中的字_论文中做出CNS高逼格的主成分分析图教程
  20. 半导体代理商名录---芯片代理商、MLCC代理商

热门文章

  1. icon font 网站推荐
  2. 维护斐波那契数列通项公式
  3. Biotin-MAL I;生物素化怀槐凝集素I(MAL I)
  4. 利用python进行用户行为分析
  5. Springboot实现定时器quartz应用举例。
  6. 7-60 高速公路超速处罚 (15 分)
  7. App界面设计规范-字体规范
  8. java 千分之一的概率,世界上几十亿人,两个人相遇的概率为千分之一
  9. SpringBoot 中 starts ---场景启动器
  10. 【毕设记录】Stata稳健性检验~ Robustness