JSBridge:Web与Native的桥梁

102 阅读6分钟

最近哈士奇提到的JSBridge让很多面试官都问上了,但是哈士奇从来没有总结说明究竟什么是JSBridge,它究竟发挥了什么作用,因此,今天哈士奇写下了这一篇文章,希望能帮助到大家。

在上一篇文章中,哈士奇和大家聊到Native的相关的问题,我们都知道Native在移动端App的开发中有着不可替代的优势,但是H5实际上是作为一种更加方便开发的方式而存在的,我们可以通过离线化的方法让H5更快发布并让用户使用到,而使用Native开发可能会碰到用户经常需要重新下载安装包的问题,如何能够使用H5与原生通信而让我们的前端应用更加快速方便的让用户使用到,这样以来JSBridge应运而生。

什么是 JSBridge?

JSBridge 是一种用于在 Web 应用中的 JavaScript 与移动端(iOS/Android)原生代码之间进行通信的机制。它允许 Web 应用与设备原生功能(如相机、文件系统、传感器等)进行交互,从而弥补了 Web 应用与原生应用之间的功能差距。

通常,JSBridge 被用在 WebView 中,帮助混合应用(Hybrid Apps)或者 H5 。通过 JSBridge,Web 前端开发人员可以调用原生应用的能力,原生应用也可以通过 JSBridge 与 Web 页面通信。

JSBridge 的工作原理

JSBridge 的核心思想是通过一个中介桥梁(Bridge),将 JavaScript 调用映射到原生应用的功能或 API 上。这个桥梁的实现方式因平台而异,但整体流程如下:

  1. JavaScript 调用原生功能:通过 JSBridge,JavaScript 代码可以向原生应用发送请求,要求调用一些系统级功能(如打开相机、获取位置信息等)。
  2. 原生应用处理请求:原生应用接收来自 JS 的请求,处理对应的逻辑,然后返回结果给 JS。
  3. JavaScript 处理结果:JSBridge 返回结果后,JavaScript 可以继续处理这些返回值并进行后续操作。

JSBridge 常见的实现方式

  1. 通过 URL Scheme (早期方法)

    最早的 JSBridge 实现是通过 URL Scheme 来实现的。这种方式是通过 WebView 在浏览器的 URL 中嵌入原生指令。当 JavaScript 修改 URL 并指定 Scheme 时,WebView 会拦截这个 URL,并由原生层来解析和处理这个请求。例如:

    • JS 端:

      window.location.href = 'myapp://invokeNativeFunction?param1=value1&param2=value2';
      
    • 原生端(拦截 URL 并处理):

      // iOS 中拦截 WebView 的 URL
      func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
          let urlString = request.url?.absoluteString
          if urlString?.hasPrefix("myapp://") {
              // 解析参数并调用原生函数
              return false // 阻止 WebView 加载该 URL
          }
          return true
      }
      
  2. 通过 JavaScript Interface (现代方法)

    现代 WebView 提供了更为直接的通信方式,比如 iOS 上的 WKWebView 和 Android 上的 WebView 都提供了专门的 JavaScript 接口(JavaScriptInterface 或者 WKScriptMessageHandler),可以更安全地让 JavaScript 调用原生代码。

    • iOS (WKWebView) 实现: 在 iOS 中,使用 WKWebViewWKScriptMessageHandler 接口,可以让 JavaScript 通过 window.webkit.messageHandlers.<name>.postMessage() 与原生通信。

      // JS 端调用
      window.webkit.messageHandlers.invokeNative.postMessage({param1: 'value1', param2: 'value2'});
      

      原生端通过实现 WKScriptMessageHandler 来处理消息:

      class WebViewController: UIViewController, WKScriptMessageHandler {
          func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
              if message.name == "invokeNative" {
                  let params = message.body as! [String: Any]
                  // 处理参数并调用原生功能
              }
          }
      }
      
    • Android (WebView) 实现: 在 Android 中,使用 addJavascriptInterface() 方法,可以将 JavaScript 调用映射到 Android 原生代码:

      // JS 端调用
      window.android.invokeNative('Hello from JS');
      

      原生端通过 addJavascriptInterface() 注入方法:

      webView.addJavascriptInterface(object {
          @JavascriptInterface
          fun invokeNative(message: String) {
              // 处理来自 JS 的消息
          }
      }, "android")
      
  3. 通过异步回调

    通常,JSBridge 会设计成异步回调机制。JavaScript 发起请求后,原生端在处理完成后将结果通过回调传递给 JS。实现方式通常如下:

    • JavaScript 调用

      JSBridge.invoke('nativeFunction', {param: 'value'}, function(response) {
          console.log('Native response: ', response);
      });
      
    • 原生端处理并回调: 原生代码处理后,会通过类似于 window.JSBridge.callback(response) 的方式回调 JavaScript,传递执行结果。

JSBridge 的典型使用场景

  1. 调用原生设备功能
    JavaScript 调用原生 API,比如打开相机、获取地理位置、扫描二维码等。

    • 示例:Web H5 页面需要调用手机摄像头拍照并上传图片。
  2. 处理支付、分享等系统级操作
    混合应用(Hybrid App)可能需要通过原生 SDK 完成支付、分享等功能。

  3. 数据同步与存储
    有时候 Web

页面需要与原生应用共享数据,比如同步用户状态、存储用户偏好设置等。这些操作可以通过 JSBridge 访问原生的持久化存储机制(如本地数据库或文件系统)。

  1. 提升 WebView 性能
    在复杂的 Web 应用中,一些高计算量的任务(如图片处理、加密解密)可以通过 JSBridge 交给原生代码处理,以减少 WebView 的计算开销,提高应用性能。

  2. 错误监控与日志上传
    当 Web 页面遇到错误时,可以通过 JSBridge 调用原生功能,上传错误日志或者收集设备信息,帮助诊断问题。

JSBridge 的优势与挑战

优势

  • 扩展性强:通过 JSBridge,Web 应用可以使用设备的原生功能,实现更加丰富的功能和更好的用户体验。
  • 提升性能:将复杂的计算和硬件操作交给原生处理,可以提高应用的整体性能,尤其是在处理媒体文件或硬件交互时。
  • 代码复用:混合应用架构允许开发者使用同样的代码库在多个平台上运行(Web + 原生),降低开发和维护成本。

挑战

  • 安全性问题:由于 JSBridge 可以执行原生代码,如果没有合理的权限管理和安全验证,可能会被恶意 JavaScript 利用,造成安全风险。
  • 平台差异性:不同的移动平台有不同的 API 和通信方式,因此开发者需要处理跨平台的兼容问题。
  • 调试复杂性:在混合应用中,Web 和原生的集成涉及多个技术栈,调试可能变得更加复杂。

总结

JSBridge 是一种重要的技术桥梁,它连接了 Web 应用和移动原生应用的世界。通过这种机制,开发者可以构建功能丰富的混合应用,结合 Web 和原生的优点,提供更加流畅、完整的用户体验。在现代移动应用开发中,JSBridge 在支付、分享、摄像头调用、性能优化等场景中广泛应用,是 Web 和原生世界互联互通的关键工具。