资讯动态

H5与小程序通信

发布时间:2026/9/24 22:09:31 来源:尧图企业网站定制
‍ 写在开头点赞 收藏 学会一句话拿走H5 嵌进小程序 web-view 后想传数据、想跳转页面靠的不是普通 JS而是微信给的一根桥——这篇文章把这根桥的用法和最容易踩的 2 个坑一次讲清。一、先说一个你可能正在经历的痛你用 uni-app 辛辛苦苦写了一个 H5 页面老板来了一句“这东西挺好塞进咱们小程序里吧。”你心想这还不简单小程序不是有个 web-view 组件么把链接往里一填完事。结果一跑起来傻眼了H5 里想告诉小程序用户下单了小程序那边纹丝不动H5 里想跳到小程序的某个原生页面也跳不过去。两边就像隔着一道玻璃墙看得见摸不着。这不是你代码写错了而是你还没搭桥。二、为什么必须搭桥web-view 本质是一个浏览器容器。你的 H5 页面跑在这个容器里而小程序原生的页面跑在容器外面。它们之间是隔离的普通的 localStorage、window 变量甚至普通的事件都穿不过那道墙。要想让墙里墙外说上话就得用微信官方提供的一套通信机制。你可以把它理解成墙上有个对讲机H5 按住说话小程序松开收听。三、这根桥长什么样先理清两个东西新手特别容易搞混微信官方提供的微信在 web-view里给 H5 开放了一套通信接口叫 wx.miniProgram.比如 wx.miniProgram.postMessage、wx.miniProgram.navigateTo。它属于微信 JS-SDK——也就是我们项目里 jweixin-1.6.0.js 那份从 res.wx.qq.com 加载。这是微信原生的接口。DClouduni-app 官方提供的叫 uni.webview.js。它是一层跨平台封装——你只管写统一的 uni.API它会自动检测当前平台把调用转发到对应原生桥在微信里转给 wx.miniProgram.在 App 里转给 plus.webview.在百度/字节小程序里各自转给它们自己的桥。对 uni-app 开发者来说直接用 uni.webview.js 最省事一份代码多端通用。所以本文示例都用 uni.* 来写记住这里的 uni 来自 DCloud 的桥接 SDK不是微信的也不是 uni-app 框架运行时的那个 uni。它给我们几个关键能力下面统一用 webView 表示你保存的桥接引用 window.__uniWebView别直接写全局 uni原因见后面的坑 2webView.getEnv(callback)判断当前到底运行在什么环境微信小程序App还是普通浏览器webView.postMessage({ data })H5 向小程序喊话把数据传过去webView.navigateTo / navigateBack / switchTab / reLaunch / redirectTo 等确实能指挥小程序做页面跳转。在微信端这些调用最终等价于微信官方为 web-view 内 H5 开放的 wx.miniProgram.navigateTo 等接口微信文档明确支持。但要注意两点url 必须是小程序原生页面路径如 /pages/detail/detail且要在宿主小程序的 pages.json 里注册过否则跳转会失败一旦跳转当前 H5 页面会被原生页面替换掉——你是从 web-view 回到/切到小程序页面而不是在 H5 内部跳。而小程序那头只要在 web-view上挂一个 bindmessage 监听器就能收到 H5 喊的话web-view src“https://你的H5地址.com/” bindmessage“onWebviewMessage”// 小程序页面的 js Page({onWebviewMessage(e){// e.detail{data}data 是一个【数组】 // 数组里的每一个元素都是 H5 某一次 postMessage({data: X})里传的那个 X // 注意是多次 postMessage 的参数累积成的数组不是单个对象 console.log(收到 H5 的消息数组, e.detail.data)e.detail.data.forEach((msg, i){console.log(第 ${i 1}条消息, msg)})}})H5 那一头发消息就一句话webView.postMessage({data:{action:userMessage, content:你好小程序}})看起来是不是很轻松别急新手 99% 会卡在下面两个坑。四、新手最容易踩的 2 个坑坑 1postMessage 发了小程序却听不见很多新手写完上面的代码兴冲冲测试发现小程序端的 onWebviewMessage 根本不触发。原因很反直觉postMessage 的消息不是实时送达的。 微信规定H5 发的数据只有在下面这些特定时机bindmessage 回调才会被触发、小程序才能收到小程序后退的时候组件被销毁的时候用户点击分享的时候用户点击复制链接的时候基础库 2.31.1 起支持所以如果你只是发个消息、页面还停在原地小程序当然收不到。另外要强调回调参数的结构e.detail { data }其中 data 是一个数组数组里的每个元素对应 H5 的每一次 postMessage({ data: X }) 传进去的那个 X。也就是说从上一次回调到这一次回调之间你调了几次 postMessage数组里就有几个元素。经常有新手直接 e.detail.data.content 去取值结果拿到 undefined——因为 data 是数组要 e.detail.data[0].content 或遍历才对。破解办法发完消息后紧跟一个 navigateBack让页面后退消息就会顺手被带过去webView.postMessage({data:{action:userMessage, content: this.message}})webView.navigateBack({delta:1})// 让小程序即时收到坑 2uni 被掉包了这个坑特别阴。我们项目 index.html 里先加载了 uni.webview.js它会往 window.uni 上挂一个桥接版 uni来自 DCloud。可随后 uni-app 框架跑起来又会在 window.uni 上挂它自己的运行时对象于是桥接版 uni 被框架版 uni 覆盖了。结果你调用 webView.postMessage你以为调的是桥接版实际调的却是 uni-app 框架的版本——它并不负责 web-view 通信自然就失灵了。破解办法在入口 index.html 里趁着 uni.webview.js 刚加载完、还没被框架覆盖先把桥接版真身存一份scriptsrc/static/uni.webview.1.5.8.js/scriptscript// 抢先保存 web-view SDK 的引用防止被 uni-app 框架的 uni 覆盖 window.__uniWebViewwindow.uni;/script之后 H5 页面里统一用这份备份来通信const webViewwindow.__uniWebView||{}webView.getEnv((res){/* 判断环境 */})webView.postMessage({data:{action:userMessage, content:hello}})记住这句话就够了在 uni-app 项目里玩 web-view 通信永远用你自己保存的那份 uni别用全局的。五、一个开箱即用的调试桥接页为了少走弯路我做了一个最小可运行的调试页项目名 h5-debug-bridge专门用来联调 H5 和小程序的通信。它干了几件贴心的事自动显示当前环境打开页面顶部就告诉你现在是在微信小程序“App还是普通浏览器”不用自己打 log 猜。一键测试发消息输入框填内容点按钮就用 postMessage 发过去并自动后退触发接收。页面跳转全家桶把 navigateTo / navigateBack / switchTab / reLaunch / redirectTo 都做成按钮挨个试跳转行为。内置 VConsole真机扫码就能看 console 日志不用连电脑调试。对初学者来说把这个项目跑起来、配合一个小程序壳子几分钟就能把整套通信逻辑摸透。六、上手三步走照抄版第一步小程序端放一个 web-view 容器web-viewsrchttps://你的H5域名.com/bindmessageonWebviewMessage/第二步H5 端引入 uni.webview.js并抢先保存引用在 index.html 里加上面坑 2那段保存代码页面里统一用 window.__uniWebView。第三步传数据 接收数据H5 发webView.postMessage({ data: {…} })需要即时送达就紧跟 navigateBack小程序收在 bindmessage 对应的 onWebviewMessage 里读 e.detail.data七、写在最后H5 与微信小程序的通信核心就三件事引入 JSSDK、用 postMessage 传话、在 bindmessage 里收话。剩下的基本都是围绕上面那两个坑打转。把提前保存 uni 引用和发完消息要后退这两点刻进肌肉记忆你就能甩开 90% 的新手。如果对您有所帮助欢迎您点个关注我会定时更新技术文档大家一起讨论学习一起进步。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价