鸿蒙和rn怎么实现原生与webview的通信

鸿蒙(HarmonyOS)React Native(RN) 中,Web 与原生(Native)之间的通信机制与 Android/iOS 有显著不同。下面分别说明它们的通信方案,并对比实现方式。


一、鸿蒙(HarmonyOS)中的 Web 与 Native 通信

鸿蒙使用 WebComponent(@ohos:web.webview) 来加载网页,通信主要通过 registerJavaScriptProxypostMessage(Web → Native) + callHandler(Native → JS) 实现。

✅ 1. Native → JS(调用网页方法)

typescript 复制代码
ts
编辑
1// ArkTS / HarmonyOS
2import web_webview from '@ohos:web.webview';
3
4@Entry
5@Component
6struct WebViewExample {
7  controller: web_webview.WebviewController = new web_webview.WebviewController();
8
9  build() {
10    Column() {
11      Web({ src: 'https://example.com', controller: this.controller })
12        .onPageEnd(() => {
13          // 页面加载完成后,调用 JS 函数
14          this.controller.callHandler('sayHelloFromNative', ['鸿蒙你好!']);
15        })
16    }
17  }
18}

✅ 2. JS → Native(网页调用原生能力)

步骤 1:定义原生对象(需 @Entry@Component 外部)

php 复制代码
ts
编辑
1class JsCallback {
2  showToast(msg: string): void {
3    // 调用鸿蒙 API,如弹窗
4    console.log('Native received:', msg);
5    // 可调用 promptAction.showToast 等
6  }
7
8  getDeviceInfo(): string {
9    return JSON.stringify({
10      platform: 'HarmonyOS',
11      version: '4.x'
12    });
13  }
14}

步骤 2:注册 JavaScript 代理

javascript 复制代码
ts
编辑
1Web({ src: 'local.html', controller: this.controller })
2  .registerJavaScriptProxy(new JsCallback(), 'harmonyBridge')
3  .onPageEnd(() => {
4    // 确保代理已注入
5  })

步骤 3:Web 端调用

xml 复制代码
html
预览
1<!-- local.html -->
2<script>
3  function callNative() {
4    harmonyBridge.showToast('Hello from Web!');
5    const info = harmonyBridge.getDeviceInfo();
6    console.log(info);
7  }
8</script>
9<button onclick="callNative()">Call HarmonyOS</button>

特点

  • 类似 Android 的 addJavascriptInterface
  • 方法自动暴露,无需注解
  • 支持同步返回值(JS 可直接接收)

二、React Native(RN)中的 Web 与 Native 通信

RN 官方不直接支持 WebView 双向通信,需借助 react-native-webview 第三方库(由社区维护,Facebook 官方推荐)。

✅ 1. 安装依赖

bash 复制代码
bash
编辑
1npm install react-native-webview
2# iOS 需 pod install

✅ 2. JS(React Native) ↔️ Web 通信

方式 A:injectedJavaScript + onMessage(最常用)

ini 复制代码
tsx
编辑
1import { WebView } from 'react-native-webview';
2
3const MyWeb = () => {
4  const webViewRef = useRef<WebView>(null);
5
6  const onMessage = (event: any) => {
7    const data = JSON.parse(event.nativeEvent.data);
8    if (data.type === 'GET_USER_INFO') {
9      // 返回数据给 Web
10      webViewRef.current?.postMessage(JSON.stringify({
11        type: 'USER_INFO_RESPONSE',
12        payload: { name: 'Alice', id: 123 }
13      }));
14    }
15  };
16
17  const injectedJs = `
18    (function() {
19      window.ReactNativeWebView.postMessage(JSON.stringify({
20        type: 'GET_USER_INFO'
21      }));
22    })();
23  `;
24
25  return (
26    <WebView
27      ref={webViewRef}
28      source={{ uri: 'https://your-web.com' }}
29      onMessage={onMessage}
30      injectedJavaScript={injectedJs}
31      injectedJavaScriptForMainFrameOnly={true}
32    />
33  );
34};

Web 端监听消息:

javascript 复制代码
js
编辑
1// Web 页面
2window.addEventListener('message', (e) => {
3  const data = JSON.parse(e.data);
4  if (data.type === 'USER_INFO_RESPONSE') {
5    console.log('User:', data.payload);
6  }
7});
8
9// Web 向 RN 发消息
10window.ReactNativeWebView.postMessage(JSON.stringify({
11  type: 'SHARE_CONTENT',
12  content: 'Hello RN!'
13}));

⚠️ 注意:window.ReactNativeWebView.postMessagereact-native-webview 注入的全局对象。


✅ 3. 高级:使用 injectJavaScript 动态调用

csharp 复制代码
ts
编辑
1// RN 中动态执行 JS
2webViewRef.current?.injectJavaScript(`
3  window.handleNativeCall({ from: 'RN', time: ${Date.now()} });
4  true; // 必须返回值
5`);

三、对比总结

平台 通信方式 Web → Native Native → Web 是否支持返回值 安全性
HarmonyOS registerJavaScriptProxy + callHandler bridge.method() controller.callHandler() ✅ 同步返回 中(需校验来源)
React Native react-native-webview + postMessage window.ReactNativeWebView.postMessage() webViewRef.postMessage()injectJavaScript ❌ 异步(需回调) 中(可启用 origin 白名单)
Android addJavascriptInterface / postWebMessage Android.method() / port.postMessage evaluateJavascript / port.postMessage ✅ / ✅ 中 / 高
iOS WKScriptMessageHandler webkit.messageHandlers.xxx.postMessage evaluateJavaScript ❌(需手动回调)

四、最佳实践建议

🟢 鸿蒙(HarmonyOS)

  • 使用 registerJavaScriptProxy 暴露最小必要接口
  • onPageBegin/onPageEnd 中控制通信时机
  • 对敏感操作增加权限校验

🟢 React Native

  • 始终使用 react-native-webview(不要用旧版 WebView
  • 启用 originWhitelist={['https://your-domain.com']}
  • 消息格式统一(如 { type, payload }
  • 避免在 injectedJavaScript 中写复杂逻辑

五、未来趋势

  • 鸿蒙 :正逐步完善 Web 能力,未来可能支持更标准的 MessageChannel
  • React Native :社区推动 WebView 新架构,但短期内仍依赖 postMessage
相关推荐
游戏开发爱好者86 小时前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
2501_915106328 小时前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
2501_915918411 天前
在 iOS 环境下查看 App 详细信息与文件目录
android·ios·小程序·https·uni-app·iphone·webview
2501_916007471 天前
没有 Mac 用户如何上架 App Store,IPA生成、证书与描述文件管理、跨平台上传
android·macos·ios·小程序·uni-app·iphone·webview
2501_915106322 天前
当 Perfdog 开始收费之后,我重新整理了一替代方案
android·ios·小程序·https·uni-app·iphone·webview
2501_915918412 天前
中小团队发布,跨平台 iOS 上架,证书、描述文件创建管理,测试分发一体化方案
android·ios·小程序·https·uni-app·iphone·webview
2501_915106322 天前
iOS 如何绕过 ATS 发送请求,iOS调试
android·ios·小程序·https·uni-app·iphone·webview
2501_915918413 天前
常见 iOS 抓包工具的使用,从代理抓包、设备抓包到数据流抓包
android·ios·小程序·https·uni-app·iphone·webview
2501_915918414 天前
把 iOS 性能监控融入日常开发与测试流程的做法
android·ios·小程序·https·uni-app·iphone·webview
2501_915106327 天前
混合应用(Hybrid)安全加固,不依赖源码对成品 IPA 混淆
android·安全·小程序·https·uni-app·iphone·webview