ts 和 webview 通信

文章展示了如何在TypeScript(TS)中与WebView进行通信,通过使用`iframe.contentWindow.postMessage`方法发送消息,以及在Webview的JavaScript中监听并响应这些消息。同样,也演示了WebView如何向TS发送消息并由TS进行监听处理,这种通信机制在多层嵌套或组件间交互时非常有用。

TS=>webView

this.webView["_impl"]._iframe.contentWindow.postMessage(“showsidePanel”, “*”);

webview 监听

window.addEventListener(‘message’, function (e) {

if( e.data == “showsidePanel”)

{

}

});

webview=》ts

window.parent.postMessage(“openGame”, ‘*’);

ts监听

window.addEventListener(‘message’, (e) => {

if (“openGame” == e.data ) {

}

})

webview可以在js里监听和发送消息 也可以在html的 里

<think> 我们正在处理的是 uniapp + vue3 的 APP 端嵌入 webview 并实现双向通讯的问题。根据引用资料,我们可以总结如下: 1. **APP 向 WebView 发送消息**:主要使用 `evalJS` 方法执行 WebView 页面中的 JavaScript 函数。 2. **WebView 向 APP 发送消息**:主要使用 `uni.postMessage` 方法(需要引入 uni.webview.js 库),然后在 APP 端通过 `@message` 事件监听。 在 vue3 中,我们需要注意: - 引用[3]提到,在 vue3 中需要直接引入 `uni.webview.js` 文件,然后在需要的地方调用 `webUni.postMessage`。 - 引用[2]展示了在 vue3 中使用 `@message` 事件监听 WebView 的消息。 下面我们分别详细说明两种方向的通讯: ### 一、准备工作 在 H5 页面中,我们需要引入 `uni.webview.js` 库,以便使用 `uni.postMessage` 方法。引用[5]给出了引入方式: ```html <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script> ``` ### 二、APP 向 WebView 发送消息 在 APP 端,我们需要获取到 WebView 的实例,然后通过 `evalJS` 方法调用 WebView 页面中的全局函数。 在 vue3 的 setup 语法糖中,我们可以这样操作: 1. 首先,在 WebView 页面中定义一个全局函数,用于接收 APP 发来的消息。例如: ```javascript window.receiveMessageFromApp = function(data) { console.log('收到APP消息:', data); // 处理消息 }; ``` 2. 在 APP 端,通过以下方式发送消息: ```vue <template> <view> <web-view :src="webviewUrl" @message="handleH5Message" ref="myWebView"></web-view> </view> </template> <script setup> import { ref, onMounted } from 'vue'; const myWebView = ref(null); // 用于获取web-view组件的引用 const webviewUrl = ref('https://your-h5-page.com'); // 向WebView发送消息 function sendToWebView() { // 获取当前页面关联的WebView对象(原生WebView) const currentWebview = uni.getCurrentSubNVue()?.id ? uni.getCurrentSubNVue() : uni.getWebviewById(uni.getCurrentPages()[0].$getAppWebview().id); // 注意:上面的获取方式可能因版本而异,下面提供另一种获取方式 // 由于在vue3中,直接通过ref获取web-view组件,然后获取其底层WebView对象 // 但uniapp的web-view组件并没有直接暴露evalJS方法,因此我们需要通过uni的API获取当前页面的WebView对象 // 方法二:通过页面对象获取 const pages = getCurrentPages(); const page = pages[pages.length - 1]; const webview = page.$getAppWebview(); // 获取web-view子WebView(因为web-view是当前页面的一个子view) const wv = webview.children()[0]; // 使用evalJS方法 const message = { type: 'GREETING', content: 'Hello from App' }; wv.evalJS(`receiveMessageFromApp(${JSON.stringify(message)})`); } </script> ``` ### 三、WebView 向 APP 发送消息 1. 在 WebView 的 H5 页面中,使用 `uni.postMessage` 发送消息: ```javascript // 在H5页面中 function sendToApp() { uni.postMessage({ data: { action: 'some_action', data: { key: 'value' } } }); } ``` 2. 在 APP 端,通过 `@message` 事件监听: ```vue <template> <web-view :src="webviewUrl" @message="handleMessage"></web-view> </template> <script setup> function handleMessage(event) { const message = event.detail.data[0]; // 注意:event.detail.data是一个数组,取第一个元素 console.log('收到H5消息:', message); // 处理消息 } </script> ``` ### 四、在 vue3 中引入 uni.webview.js 的处理(引用[3]) 引用[3]提到,在 vue3 中,需要在页面中直接引入 `uni.webview.js` 文件,然后调用其方法。但注意,这个引入是在 WebView 的 H5 页面中,而不是在 uniapp 的 APP 页面中。 然而,如果我们希望在 uniapp 的 vue3 页面中控制 WebView通信,我们只需要按照上述方式使用 `@message` `evalJS` 即可。 ### 五、注意事项 1. **引入 uni.webview.js**:WebView 的 H5 页面必须引入该库,否则 `uni.postMessage` 不可用。 2. **安全考虑**:在 WebView 中,可以通过 `navigator.userAgent` 判断是否在 uniapp 的 WebView 中,以决定是否使用 `uni.postMessage`。 3. **调试**:在开发时,可以在 APP 端打印 WebView 对象,确保正确获取。 ### 六、完整示例(vue3) **APP 端(uniapp 页面)**: ```vue <template> <view> <button @click="sendToWebView">发送消息到WebView</button> <web-view :src="webviewUrl" @message="handleH5Message" ref="myWebView"></web-view> </view> </template> <script setup> import { ref } from 'vue'; const webviewUrl = ref('http://your-h5-domain.com/path'); const myWebView = ref(null); // 实际上,在APP端我们通常不通过这个ref来操作,而是通过页面对象 function handleH5Message(event) { console.log('接收到H5的消息:', event.detail.data[0]); } function sendToWebView() { // 获取当前页面的webview const pages = getCurrentPages(); const currentPage = pages[pages.length - 1]; const webview = currentPage.$getAppWebview(); // 获取web-view对应的子WebView const wv = webview.children()[0]; if (wv) { // 构建要传递的数据 const data = { command: 'changeColor', color: '#ff0000' }; wv.evalJS(`window.postMessageFromApp && window.postMessageFromApp(${JSON.stringify(data)})`); } } </script> ``` **H5 页面**: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>H5 Page</title> <script src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script> <script> // 接收APP消息的函数 window.postMessageFromApp = function(data) { console.log('Received from App:', data); // 例如,改变背景色 if (data.command === 'changeColor') { document.body.style.backgroundColor = data.color; } }; // 发送消息给APP function sendMessageToApp() { uni.postMessage({ data: { type: 'from_h5', message: 'Hello from H5' } }); } </script> </head> <body> <button onclick="sendMessageToApp()">发送消息到APP</button> </body> </html> ``` ### 七、相关问题 1. 如果 H5 页面不是自己开发的,如何实现通信? 2. 在 uniapp 的 APP 端,如何确保 `evalJS` 执行时 WebView 已经加载完成? 3. 除了 `evalJS` `uni.postMessage`,还有其他通信方式吗? 4. 如何处理大量数据的传输? [^1]: uniapp实现与webview之间的相互通讯。基于uniapp开发在一些特殊场景,可能会用到app嵌套h5或h5嵌套h5的场景,uniapp中有一个web-view组件类似于iframe我们可以基于web-view实现双向通信,以下是对不同情况下的使用总结。 [^2]: uniapp vue3中使用webview在微信小程序中实现双向通讯。vue3 ts代码 src就是项目启动的网络地址,他必须要用网络地址, scr后面拼接参数记得做处理,转成json。 [^3]: 【uniapp*vue3】app/h5 webview通讯方案。但这方案在vue3环境下是无法使用的 vue3的解决方案是直接在需要使用的页面import引入该文件 直接调用webUni.postMessage即可。 [^5]: uniapp中 app与webview的通讯。webview发送。 </think> ### Uniapp + Vue3 中实现 APP 与 WebView 双向通信方案 在 Uniapp + Vue3 环境下实现 APP 与 WebView 双向通信,主要通过 **`uni.postMessage`** API **WebView 的 `evalJS` 方法** 实现。以下是具体实现步骤: --- ### 一、通信基础配置 #### 1. WebView 页面引入通信库 在 H5 页面必须引入官方通信库: ```html <!-- H5 页面头部 --> <script src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script> ``` #### 2. APP 端 WebView 组件配置 ```vue <template> <web-view :src="webviewUrl" @message="handleH5Message" ref="myWebView" ></web-view> </template> <script setup> import { ref } from 'vue'; const webviewUrl = ref('https://your-h5-domain.com?token=app_token'); const myWebView = ref(null); // 监听 H5 发送的消息 const handleH5Message = (e) => { console.log('收到 H5 消息:', e.detail.data[0]); // 示例:{ action: "DOWNLOAD", data: "http://example.com/file.png" } }; </script> ``` --- ### 二、双向通信实现 #### 1. H5 → APP 通信(推荐方案) **H5 端发送消息:** ```javascript // H5 页面中 function sendToApp() { uni.postMessage({ data: { action: "USER_ACTION", payload: { userId: 123, type: "login" } } }); } ``` **APP 端接收:** 自动触发 `@message` 事件,数据在 `e.detail.data[0]` 中[^5] #### 2. APP → H5 通信 **APP 端发送消息:** ```vue <script setup> // 获取 WebView 实例并执行 JS const sendToH5 = () => { const page = getCurrentPages()[0]; const webview = page.$getAppWebview(); const wv = webview.children()[0]; wv.evalJS(` receiveAppMessage(${JSON.stringify({ command: "UPDATE_DATA", data: { theme: "dark", fontSize: 16 } })}) `); }; </script> ``` **H5 端接收:** ```javascript // H5 页面中声明全局函数 window.receiveAppMessage = (data) => { console.log("APP 发来指令:", data); // 根据 data.command 执行对应操作 }; ``` --- ### 三、Vue3 特定注意事项 1. **WebView 引用问题** 通过 `getCurrentPages()[0].$getAppWebview()` 获取 WebView 实例(因 Vue3 的 `ref` 无法直接获取原生对象)[^3] 2. **参数传递方案** ```vue <script setup> // URL 传参方案(初始化数据) const initParams = JSON.stringify({ userRole: "admin" }); const webviewUrl = `https://h5-domain.com?params=${encodeURIComponent(initParams)}`; </script> ``` 3. **uni.webview.js 引入优化** 在 Vue3 中推荐直接引入 JS 文件: ```javascript // 在 /static/js/uni.webview.js 存放库文件 import '@/static/js/uni.webview.js'; ``` --- ### 四、完整示例代码 #### APP 端 (Vue3) ```vue <template> <view> <button @click="sendColorToH5('#FF0000')">设置红色主题</button> <web-view :src="h5Url" @message="handleH5Msg"></web-view> </view> </template> <script setup> import { ref } from 'vue'; const h5Url = ref('https://h5-app.com?init=1'); const handleH5Msg = (e) => { const msg = e.detail.data[0]; if (msg.action === 'DOWNLOAD') { uni.downloadFile({ url: msg.url }); } }; const sendColorToH5 = (color) => { const wv = getCurrentPages()[0].$getAppWebview().children()[0]; wv.evalJS(`window.setAppTheme('${color}')`); }; </script> ``` #### H5 端 ```html <script> // 接收 APP 指令 window.setAppTheme = (color) => { document.body.style.background = color; }; // 向 APP 发送下载请求 document.getElementById('download-btn').addEventListener('click', () => { uni.postMessage({ data: { action: "DOWNLOAD", url: "http://example.com/file.zip" } }); }); </script> ``` --- ### 五、调试技巧与常见问题 1. **调试工具** - H5 端:使用 Chrome 开发者工具 - APP 端:`console.log(webview.children())` 查看 WebView 对象[^2] 2. **通信失败排查** - 检查是否引入 `uni-webview-js` 库 - 验证 URL 白名单配置(manifest.json → App SDK 配置) - 确保 H5 方法为 **全局函数**(挂载到 window) 3. **安全增强建议** ```javascript // H5 端验证运行环境 if (!window.uni || !uni.postMessage) { console.error("非 uni 环境,禁用通信"); } ``` --- ### 相关问题 1. 如何处理 WebView 加载失败的情况? 2. 如何实现 APP WebView 之间的登录状态同步? 3. 在 WebView 中如何调用 APP 的原生功能(如相机)? 4. 通信数据量较大时应该采用什么优化策略? [^1]: uniapp实现与webview之间的相互通讯 [^2]: uniapp vue3中使用webview在微信小程序中实现双向通讯 [^3]: 【uniapp*vue3】app/h5 webview通讯方案 [^5]: uniapp中 app与webview的通讯
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值