在混合开发(hybrid app)中,web 与 native(android/ios)之间的通信是核心需求。常见的三种通信方式是:
- jsbridge(基于 addjavascriptinterface / wkscriptmessagehandler)
- postmessage + messagechannel(现代 webview 通信)
- url scheme(拦截自定义协议)
下面从 原理、区别、安全性、平台实现 等维度详细对比,并给出 android 和 ios 的实现方式。
一、三种方式概览对比
| 特性 | jsbridge | postmessage(messagechannel) | url scheme |
|---|---|---|---|
| 通信方向 | 双向(js → native,native → js) | 双向(更标准) | 主要 js → native |
| 实时性 | 高 | 高(异步消息通道) | 中(依赖页面跳转/iframe) |
| 安全性 | 中(需谨慎暴露接口) | 高(沙箱隔离) | 低(易被中间人劫持) |
| 兼容性 | android ≥ api 17;ios ≥ wkwebview | android ≥ 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 足够 |
四、最佳实践建议
- 永远启用 https,防止中间人注入恶意 js。
- 验证 webview 加载的域名(白名单),避免第三方页面调用你的 native 接口。
- 不要在 jsbridge 中暴露敏感操作(如读取文件、获取 token)。
- 对 url scheme 参数做签名或加密,防止伪造。
- 优先使用 wkwebview(ios)和 androidx webview(android) ,避免使用过时的
uiwebview或系统 webview。
到此这篇关于jsbridge、postmessage、scheme三种通信方式的区别以及安卓ios实现方式的文章就介绍到这了,更多相关jsbridge、postmessage、scheme通信方式内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论