Lee
Photo by raffaele brivio
Lee
Lee
Published at Mar 31, 2020 · 4 mins to read

JSBridge:连接 Web 与 Native 的通信桥梁

Contents

为什么需要 JSBridge

在移动应用开发中,Native AppWeb App 各有千秋:

Hybrid App 结合两者优势:

JSBridge 正是实现两者无缝协作的关键桥梁,JSBridge 的使命:

典型应用场景:

JSBridge 的核心原理

通信的基础:WebView

WebView 是 Native App 内嵌的浏览器引擎,负责渲染 Web 内容并提供 JS 与 Native 的交互通道。

双向通信机制

JSBridge 的核心是双向方法调用与数据传递:

通信需注意主线程安全、数据序列化、错误处理。

JavaScript 调用 Native 的三种方式

URL Scheme 拦截 (早期方案)

注入全局 API (经典方案)

MessageChannel 通信 (现代推荐方案)

JSBridge 的设计与实现

协议设计

通信双方需约定统一的协议格式,常见格式如下:

// request example
{
  "jsonrpc": "2.0",
  "id": "req_1234567890",
  "method": "camera.takePhoto",
  "params": {
    "quality": "high",
    "allowEdit": true
  }
}

// response example
{
  "jsonrpc": "2.0",
  "id": "req_1234567890",
  "result": {
    "base64": "data:image/jpegbase64,..."
  },
  "error": null
}

Native 端的实现

iOS(Swift + WKWebView):

Android(Kotlin + WebView):

Web 端的实现

class JSBridge {
  private callbacks = new Map<string, { resolve: Function reject: Function }>()
  private seq = 0

  constructor() {
    // listen for messages from Native
    window.addEventListener('message', (event) => {
      const data = event.data
      if (data && data.id && this.callbacks.has(data.id)) {
        const cb = this.callbacks.get(data.id)!
        data.error ? cb.reject(data.error) : cb.resolve(data.result)
        this.callbacks.delete(data.id)
      }
    })
  }

  call<T = any>(method: string, params: any = {}): Promise<T> {
    return new Promise((resolve, reject) => {
      const id = `req_${Date.now()}_${this.seq++}`
      this.callbacks.set(id, { resolve, reject })

      const message = { jsonrpc: '2.0', id, method, params }

      // send message to Native
      if (window.NativeBridge?.postMessage) {
        window.NativeBridge.postMessage(JSON.stringify(message))
      } else if ((window as any).webkit?.messageHandlers?.JSBridge?.postMessage) {
        (window as any).webkit.messageHandlers.JSBridge.postMessage(message)
      } else {
        // fallback URL Scheme
        const iframe = document.createElement('iframe')
        iframe.style.display = 'none'
        iframe.src = `jsbridge://${encodeURIComponent(JSON.stringify(message))}`
        document.body.appendChild(iframe)
        setTimeout(() => iframe.remove(), 100)
      }

      // timeout handling
      setTimeout(() => {
        if (this.callbacks.has(id)) {
          reject(new Error('JSBridge call timeout'))
          this.callbacks.delete(id)
        }
      }, 10000)
    })
  }

  // register methods for Native to call
  register(method: string, handler: Function) {
    (window as any)[method] = handler
  }
}

// usage example
const bridge = new JSBridge()

bridge.call('user.getInfo').then(info => console.log(info))

bridge.register('web.showToast', (msg: string) => alert(msg))

JSBridge 的优缺点与应对策略

优点

缺点与解决方案

性能问题

场景:频繁通信或大数据传输可能引发卡顿。 优化:

安全性风险

兼容性问题

最佳实践

协议标准化

错误处理

安全保障

性能监控

未来趋势

更高效的通信方案:如基于 WebAssembly 的跨语言调用。 跨平台框架整合:如 Flutter 通过自渲染引擎减少对 WebView 的依赖。

总结

JSBridge 是 Hybrid 开发的核心技术,它通过 WebView 的通信能力,将 Web 的动态化与 Native 的高性能结合。尽管存在性能、安全等挑战,但通过合理的协议设计、错误处理和性能优化,可以构建出稳定高效的混合应用。

闽ICP备14017690号-8