UniApp 内嵌 H5 通信全攻略

概述

在混合开发中,App 内嵌 H5 是复用 Web 资源、实现动态更新的常见手段(如:活动页面、广告、内部页面)。 这篇文章会拆解双向通信的核心流程,并给出经过验证的代码模板。

通信架构总览

UniApp 的 web-view 在不同平台底层实现差异很大:App 端是原生 webview 渲染,微信小程序端是沙箱隔离的 iframe,H5 端则直接转成了 iframe。

但通信 API 的设计是统一的:

  • H5 → App :H5 调用 uni.postMessage,App 在 <web-view> 的 @message 事件中接收。
  • App → H5 :App 通过 webviewContext.evalJS() 执行 H5 侧的 JS 函数,实现数据注入或方法调用。

前置准备:引入 JSBridge

无论 H5 项目是用什么框架写的,通信前都必须引入 uni.webview.js。这个文件提供了 uni.postMessage 和平台环境探测能力。

html

xml 复制代码
<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></script>

关键注意点 :如果你的 H5 也是 UniApp 编译出来的,全局变量 uni 会被这个引入的 SDK 覆盖。建议把 SDK 的全局变量重命名,比如挂载到 webUni 上,避免冲突。

引入后,监听 UniAppJSBridgeReady 事件再执行业务逻辑:

javascript

javascript 复制代码
document.addEventListener('UniAppJSBridgeReady', function() {
  // 此时 uni 对象可用
  console.log('Bridge 就绪');
});

核心通信流程

场景一:H5 向 App 发送消息

H5 侧调用 uni.postMessage,数据必须包裹在 data 对象中:

javascript

php 复制代码
uni.postMessage({
  data: {
    action: 'submit',
    payload: { orderId: '12345' }
  }
});

App 侧在 <web-view> 组件上监听 @message 事件。注意一个细节 :event.detail.data 是一个数组,每次 postMessage 的消息会推入这个数组,取最新一条通常用 [0] 或 [length - 1]:

vue

xml 复制代码
<template>
  <web-view src="https://your-h5.com/page" @message="onMessage"></web-view>
</template>

<script setup>
function onMessage(event) {
  const data = event.detail.data[0];
  console.log('收到 H5 消息:', data);
}
</script>

场景二:App 主动调用 H5 方法

App 侧需要先获取 webviewContext。这里有一个版本差异需要留意 :鸿蒙平台(HarmonyOS)下 evalJS 无返回值,且 webviewContext 的创建时机和普通 Android/iOS 不同。

推荐在 onReady 生命周期中创建 context:

vue

xml 复制代码
<script setup>
import { onReady } from '@dcloudio/uni-app';
import { getCurrentInstance } from 'vue';

let webviewContext = null;

onReady(() => {
  // 条件编译:鸿蒙平台单独处理
  // #ifdef APP-HARMONY
  webviewContext = uni.createWebviewContext('myWebview', getCurrentInstance().proxy);
  // #endif

  // #ifndef APP-HARMONY
  webviewContext = uni.createWebviewContext('myWebview');
  // #endif
});

function callH5Method() {
  webviewContext.evalJS(`
    window.receiveFromApp(${JSON.stringify({ type: 'update', id: 1 })})
  `);
}
</script>

H5 侧预先定义好被调用的函数:

javascript

javascript 复制代码
window.receiveFromApp = function(params) {
  console.log('收到 App 调用:', params);
  // 执行业务逻辑
  return { status: 'ok' };
};

跨平台兼容建议

平台 关键差异 推荐做法
App 支持 evalJS 同步/异步返回,能力最全 双向通信首选方案
微信小程序 postMessage 非实时,需引入微信 SDK 配合 navigateTo 跳转传参
支付宝小程序 需引入 web-view.min.js,双向通较顺畅 可复用 uni.webview 统一封装
H5 端 web-view 被转为 iframe 直接用 window.postMessage

如果项目需要同时兼容多端,建议在 H5 侧封装一个统一的消息发送层,内部通过 uni.getEnv 判断当前环境后走对应通道。

相关推荐
百万蹄蹄向前冲1 小时前
一张平面图把学校做成2D游戏
前端·人工智能·后端
zeqinjie1 小时前
Flutter 获取 iPhone Duo 预留区位置
前端·flutter·ios
机器之心1 小时前
突发:Claude自主发现未知生物系统,或能编辑基因
前端·人工智能·后端
用户6802659051191 小时前
企业电脑统一管理怎么做?2026企业终端统一管理方法与工具推荐
javascript·后端·面试
仿生狮子1 小时前
实现近乎免费之后,设计工程师还剩什么
前端·后端·设计
EatFans1 小时前
Electron 打包与自动更新完全指南:electron-builder、latest.yml、app-update.yml 与自建更新服务器实战
前端
小凯在掘金1 小时前
为什么要有访问器? 你不知道的对象属性
前端·javascript
OpenTiny社区1 小时前
HC 2026 回顾|OpenTiny NEXT 解锁 Web 应用智能化新范式
前端·开源·github
时光少年1 小时前
Android HWC退化与防治方法
前端