uniapp 和 webview 之间的通信

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项目当中。

最新版地址:gitcode.net/dcloud/uni-...

1.UniAppJSBridgeReady :

这个是在引入webview的SDK之后,当webview页面被加载完成之后会触发,该事件触发表示着uniapp和webview之间的桥成功搭建,uni对象被成功的注入到当前H5的上下文中。 我们在index.html文件中将SDK引入,这里的SDK引入必须放在body标签下面。

html 复制代码
<!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),以防止消息被发送到不安全的地址。 主页面

html 复制代码
<!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>

内嵌页面

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>
相关推荐
曹天骄16 分钟前
Next-Auth 认证系统:用户与管理员双角色登录配置
开发语言·前端·javascript
心灵的制造商1 小时前
【CSS文字渐变动画】
前端·css
神秘代码行者1 小时前
HTML5拖拽功能教程
前端·html·html5
好_快1 小时前
Lodash源码阅读-SetCache
前端·javascript·源码阅读
好_快1 小时前
Lodash源码阅读-Stack
前端·javascript·源码阅读
uperficialyu1 小时前
2025年01月13日字节(本地生活)前端面试
前端·面试
砸吧砸吧2 小时前
#echarts#折线图#饼图
前端·javascript·echarts
BUG_Jia2 小时前
解决 uniapp 开发中权限申请同步告知目的问题| 华为应用商店上架审核问题解决
前端·javascript·css·vue.js·uni-app·css3
知识分享小能手3 小时前
CSS3学习教程,从入门到精通,CSS3 浮动与清除浮动语法知识点及案例代码(14)
前端·css·后端·学习·html·css3·html5
bin91533 小时前
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加导出数据功能示例9,TableView15_09带排序的导出表格示例
开发语言·前端·javascript·vue.js·ecmascript·deepseek