jsbridge、postMessage、scheme三种通信方式的区别和安卓ios实现方式

8 阅读3分钟

在混合开发(Hybrid App)中,Web 与 Native(Android/iOS)之间的通信是核心需求。常见的三种通信方式是:

  1. JSBridge(基于 addJavascriptInterface / WKScriptMessageHandler
  2. postMessage + MessageChannel(现代 WebView 通信)
  3. URL Scheme(拦截自定义协议)

下面从 原理、区别、安全性、平台实现 等维度详细对比,并给出 Android 和 iOS 的实现方式。


一、三种方式概览对比

特性JSBridgepostMessage(MessageChannel)URL Scheme
通信方向双向(JS → Native,Native → JS)双向(更标准)主要 JS → Native
实时性高(异步消息通道)中(依赖页面跳转/iframe)
安全性中(需谨慎暴露接口)高(沙箱隔离)低(易被中间人劫持)
兼容性Android ≥ API 17;iOS ≥ WKWebViewAndroid ≥ 6.0(API 23);iOS ≥ WKWebView全平台支持
实现复杂度中高
是否推荐✅ 常用(但注意安全)✅✅ 推荐(现代方案)⚠️ 仅用于简单场景

二、详细说明与实现

1. JSBridge(传统桥接)

✅ 原理:

  • Android:通过 WebView.addJavascriptInterface() 注入 Java 对象。
  • iOS:通过 WKWebView.configuration.userContentController.add(_:name:) 注册消息处理器。

🔐 安全要求:

  • Android 必须加 @JavascriptInterface
  • iOS 需验证来源(如域名白名单)

📱 Android 实现:

java
编辑
1// Java
2public class Bridge {
3    @JavascriptInterface
4    public void callNative(String data) {
5        // 处理 JS 调用
6    }
7}
8webView.addJavascriptInterface(new Bridge(), "Android");
javascript
编辑
1// JS
2Android.callNative("hello");

🍏 iOS 实现(Swift):

swift
编辑
1// Swift
2class BridgeHandler: NSObject, WKScriptMessageHandler {
3    func userContentController(_ controller: WKUserContentController, didReceive message: WKScriptMessage) {
4        if message.name == "iosBridge" {
5            print("收到 JS 消息:", message.body)
6        }
7    }
8}
9
10let config = WKWebViewConfiguration()
11config.userContentController.add(BridgeHandler(), name: "iosBridge")
12let webView = WKWebView(frame: .zero, configuration: config)
javascript
编辑
1// JS
2window.webkit.messageHandlers.iosBridge.postMessage("hello");

✅ 优点:简单直接,广泛使用
❌ 缺点:Android 旧版本有安全漏洞;iOS 无法直接返回值(需回调)


2. postMessage + MessageChannel(现代通信)

✅ 原理:

利用 HTML5 的 MessageChannel 创建一个双向、异步、隔离的消息通道,Native 作为另一端接收端口。

这是 Chrome 团队推荐的 WebView 通信方式,安全性高。

📱 Android 实现(API ≥ 23):

java
编辑
1webView.evaluateJavascript("(function() {" +
2    "const channel = new MessageChannel();" +
3    "channel.port1.onmessage = function(e) { console.log('Reply:', e.data); };" +
4    "window.nativePort = channel.port2;" +
5    "})()", null);
6
7// Native 发送消息到 JS
8webView.postWebMessage(
9    new WebMessageCompat("Hello from Android", new WebMessagePortCompat[]{port}),
10    Uri.parse("https://your-trusted-domain.com")
11);

注意:需配合 WebMessageListener(AndroidX)或 postWebMessage 使用。

🍏 iOS 实现(WKWebView):

iOS 的 WKScriptMessageHandler 本身不直接支持 MessageChannel,但可通过 JS 端模拟双向通信,或使用 evaluateJavaScript 返回结果。

目前 Android 对 MessageChannel 原生支持更好,iOS 仍以 messageHandlers 为主。

✅ 优点:安全、标准、支持流式通信
❌ 缺点:兼容性较差(Android < 6.0 不支持)


3. URL Scheme(拦截跳转)

✅ 原理:

JS 通过 location.href = "myapp://action?param=xxx" 触发页面跳转,Native 拦截该 URL 并解析。

📱 Android 实现:

java
编辑
1webView.setWebViewClient(new WebViewClient() {
2    @Override
3    public boolean shouldOverrideUrlLoading(WebView view, String url) {
4        if (url.startsWith("myapp://")) {
5            // 解析参数并处理
6            return true; // 拦截,不加载
7        }
8        return false;
9    }
10});

🍏 iOS 实现:

swift
编辑
1func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
2    if let url = navigationAction.request.url,
3       url.scheme == "myapp" {
4        // 处理自定义协议
5        decisionHandler(.cancel) // 拦截
6        return
7    }
8    decisionHandler(.allow)
9}

💡 技巧:避免页面跳转闪烁

  • 使用隐藏的 <iframe> 触发:

    javascript
    编辑
    1const iframe = document.createElement('iframe');
    2iframe.src = 'myapp://call?data=xxx';
    3iframe.style.display = 'none';
    4document.body.appendChild(iframe);
    5setTimeout(() => document.body.removeChild(iframe), 100);
    

✅ 优点:兼容性极好(所有 WebView 支持)
❌ 缺点:

  • 无法直接返回值(需 JS 再调一次)
  • URL 长度有限(~2000 字符)
  • 安全性差(可能被第三方页面伪造调用)

三、如何选择?

场景推荐方案
现代 App(Android ≥ 6.0,iOS ≥ 9)✅ JSBridge + 安全校验 或 postMessage(Android 优先)
需要高安全性(如金融类)✅ postMessage + 域名白名单 + HTTPS
兼容老旧设备⚠️ URL Scheme(但需加密参数、校验来源)
频繁双向通信(如聊天、实时数据)✅ JSBridge + 回调机制 或 MessageChannel
仅简单通知(如分享、埋点)✅ URL Scheme 足够

四、最佳实践建议

  1. 永远启用 HTTPS,防止中间人注入恶意 JS。
  2. 验证 WebView 加载的域名(白名单),避免第三方页面调用你的 Native 接口。
  3. 不要在 JSBridge 中暴露敏感操作(如读取文件、获取 token)。
  4. 对 URL Scheme 参数做签名或加密,防止伪造。
  5. 优先使用 WKWebView(iOS)和 AndroidX WebView(Android) ,避免使用过时的 UIWebView 或系统 WebView。