鸿蒙和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
相关推荐
2501_915106326 小时前
常见 iOS 抓包工具的使用方式与组合思路
android·ios·小程序·https·uni-app·iphone·webview
深海呐1 天前
Android WebView吊起软键盘遮挡输入框的问题解决
android·webview·android 键盘遮挡·webview键盘遮挡
REDcker3 天前
Android WebView 版本升级方案详解
android·音视频·实时音视频·webview·js·编解码
游戏开发爱好者83 天前
如何使用 AppUploader 提交上传 iOS 应用
android·ios·小程序·https·uni-app·iphone·webview
REDcker4 天前
Android WebView 升级 - WebViewUpgrade 库使用详解
android·华为·harmonyos·webview
00后程序员张4 天前
在 iPhone 上进行 iOS 网络抓包的实践经验
android·ios·小程序·https·uni-app·iphone·webview
2501_916008894 天前
没有 Mac 如何在 Windows 上创建 iOS 应用描述文件
android·macos·ios·小程序·uni-app·iphone·webview
『 时光荏苒 』5 天前
微信小程序we分析如何采集webview的体验信息
微信小程序·小程序·webview·we分析
2501_915909065 天前
iOS 应用在混淆或修改后,如何完成签名、重签名与安装测试
android·ios·小程序·https·uni-app·iphone·webview