uniapp和webview之间的通信举例详解
作者:DT——
1.背景
应用使用了uniapp开发跨端应用,在uniapp中内嵌webview页面实现页面热更新效果,不需要用户单独重新安装软件即可实现页面的版本更新。
2.webview通知uniapp
在开发过程中我们难会遇到需要uniapp和webview来实现数据通信的场景,接下来介绍一种可行的uniapp和webview的数据通信方案。
在webview中我们可以使用当前webview实例的postMessage方法来触发webview组建的onPostMessage方法来传递数据,重点就需要放在了如何将uniapp的webview实例来加入到webview的h5项目当中。
uniapp官方文档中指出可以使用uni.webview.js 这个js SDK 来将当前的uni对象注入到webview所加载的H5项目当中。
最新版地址:https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.6.js;
1.UniAppJSBridgeReady :
这个是在引入webview的SDK之后,当webview页面被加载完成之后会触发,该事件触发表示着uniapp和webview之间的桥成功搭建,uni对象被成功的注入到当前H5的上下文中。
我们在index.html文件中将SDK引入,这里的SDK引入必须放在body标签下面。
<!DOCTYPE html> <html lang="zh-CN"> <head> ... </head> <body> <noscript> <strong>Please enable JavaScript to continue.</strong> </noscript> <div id="app"></div> <!-- built files will be auto injected --> </body> <!-- uni 的 SDK --> <!-- 需要把 uni.webview.1.5.6.js 下载到自己的服务器 --> <script type="text/javascript" src="https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.6.js"></script> <script> document.addEventListener('UniAppJSBridgeReady', function() { uni.webView.getEnv(function(res) { console.log('当前环境:' + JSON.stringify(res)); }); // uni.webView.navigateTo(...) }); </script> </html>
2.webview中可用的uni API
方法名 | 说明 | 平台差异说明 |
---|---|---|
uni.navigateTo | navigateTo | |
uni.redirectTo | redirectTo | |
uni.reLaunch | reLaunch | |
uni.switchTab | switchTab | |
uni.navigateBack | navigateBack | |
uni.postMessage | 向应用发送消息 | 抖音小程序不支持、H5 暂不支持(可以直接使用 window.postMessage |
uni.getEnv | 获取当前环境 | 抖音小程序与飞书小程序不支持 |
3.发送消息
我们在H5中可以使用uni.postMessage方法来向应用发送消息,应用中的webview的onPostMessage方法会被触发,从而通过参数就可以拿到需要传递的数据。
或者因为可以使用uni.webView获取到当前webview实例,调用实例postMessage方法也可以传递数据。
注意: 这种做法在H5端是不支持的,后续会介绍H5端的处理方式。
3.uniapp 通知webview
uniapp通知webview页面,官方提供了一种巧妙地方式。在H5项目中全局暴露一个用于接收数据的函数,然后在uniapp中去触发这个函数将参数传递过去即可是实现数据的传递。
evalJS
uniapp为每一个webview组件实例挂载了一个evalJS方法,用于为webview页面注入一个可执行的js脚本代码。这段代码会在webview的全局作用域中执行。我们使用evalJS来触发一个特定的函数,在H5的全局作用域中定义对应的函数,并提前写好对应的数据处理逻辑。后续只需要在uniapp中触发evalJS即可实现数据的传递。
注意:这种方式在H5端也是不支持的,后续会介绍。
4.H5中实现数据的通信
上述介绍的webview和uniapp的通信只针对于uniapp编译的代码是非H5环境,如果是H5环境则无效。因此使用postMessage 方案替代
postMessage
window.postMessage 是一个非常强大的 Web API,用于在不同窗口或内嵌页面(如 <iframe>
)之间安全地传递消息。它允许跨源通信,即不同域名、协议或端口的页面之间可以互相发送消息。
window.postMessage 方法允许一个窗口向另一个窗口发送消息。消息的接收方可以通过监听 message 事件来接收消息。为了确保安全性,postMessage 方法需要明确指定目标窗口的来源(targetOrigin),以防止消息被发送到不安全的地址。
主页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Main Page</title> </head> <body> <h1>Main Page</h1> <iframe id="myIframe" src="https://other-origin.com/iframe.html" width="600" height="400"></iframe> <button id="sendMessage">Send Message to Iframe</button> <script> // 获取 iframe 的引用 const iframe = document.getElementById('myIframe'); // 监听按钮点击事件,向 iframe 发送消息 document.getElementById('sendMessage').addEventListener('click', () => { // 确保 iframe 已加载完成 if (iframe.contentWindow) { iframe.contentWindow.postMessage('Hello from main page!', 'https://other-origin.com'); } }); // 监听来自 iframe 的消息 window.addEventListener('message', (event) => { // 验证来源 if (event.origin !== 'https://other-origin.com') return; console.log('Received message from iframe:', event.data); }); </script> </body> </html>
内嵌页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Iframe Page</title> </head> <body> <h1>Iframe Page</h1> <button id="sendMessage">Send Message to Main Page</button> <script> // 监听按钮点击事件,向主页面发送消息 document.getElementById('sendMessage').addEventListener('click', () => { // 向父窗口发送消息 window.parent.postMessage('Hello from iframe!', '*'); }); // 监听来自主页面的消息 window.addEventListener('message', (event) => { // 验证来源 if (event.origin !== 'http://main-page-origin.com') return; console.log('Received message from main page:', event.data); }); </script> </body> </html>
总结
到此这篇关于uniapp和webview之间通信的文章就介绍到这了,更多相关uniapp和webview通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!