描述:
小程序webview内嵌的h5需要向小程序实时发送消息,有人说postMessage可以实现,所以试验一下,结果是实现不了实时,只能在特定时机后退、组件销毁、分享时小程序才能接收到信息(小程序为了安全等考虑做了限制),有人说可以使用websocker实现,这种方法应该是没问题的,就是有点麻烦,要跟后端配合。
实时通信:
小程序传参数给h5都是通过url参数,没什么好说的,主要说下h5传参数给小程序。
我是使用webview的load方法实现的,这个方法副作用就是会刷新页面,当需要通信时加载新地址以触发load事件。
const prefix = window.location.href.indexOf('?') ? '&' : '?'
window.location.href = window.location.href + prefix + `action=openMapAPP&latitude=${latitude}&longitude=${longitude}&address=${address}`
注意:
1.不要通过uni等做跳转,那样浏览器不会刷新,导致load不会触发。
2.有可能你发布后load的e.detail.src拿不到url。这个是因为只有小程序配置了业务域名才可以拿到url。
3.本地测试load拿不到url,需要修改微信开发者工具的“调试基础库”版本(详情-本地设置里面)。我测验2.21.4到2.24.7版本可以拿到url,其他版本太新或太老都不行,这有可能导致切换后项目启动报错,可以适当在2.21.4到2.24.7区间换个没问题的版本。
4.真机调试load拿不到url,需要把调试基础库推送到手机端,这个需要使用同个微信。推送后重新真机调试就行了。
做非实时通信时根据网上教程掉的坑:
postMessage有两种方式,第一种是index.html引入uni.webview.js调用uni.postMessage,第二种是引入jweixin.js调用wx.miniProgram.postMessage。
1.用第一种方式,uni.webview.js需要改源码名称,不然uni会被覆盖,这个也挺多人提到的。不过这种方式还要引入jweixin.js才能使用,改完再通过newName.postMessage调用,如果小程序控制台有输出invokeAppService postMessage ***则代表发送信息成功,奇怪的是我测试时第一天用这种方式成功了,第二天失败了还原不了。
2.我换成了第二种方式,不过跟网上其他人用法不同,别人时直接用wx.miniProgram.postMessage调用,我发现wx也是会被uni的wx对象覆盖,所以我换成npm安装weixin-js-sdk,然后使用 import wxH5 from “weixin-js-sdk” 引入,再调用wxH5.miniProgram.postMessage。这种也需要引入uni.webview.js,我在index.html引入。这个不需要改uni.webview.js源码。
3.信息发送成功后webview @message监听不到信息,需要小程序后退、组件销毁、分享时才能收到信息。注意:改变嵌套的h5是无效的,例如在h5内做路由返回,经测验,返回调用的是h5项目的返回,不能返回到webview外,可以点击小程序左上角的返回按钮来看有没有触发@message事件,所以你webview外的项目的路由至少需要两层。如果webview直接嵌套html网页,是可以直接返回到webview外的。
4.官方文档说可以直接使用 window.postMessage发送信息,测验后是不行的。这种方式只能通过window监听message事件才能接收到消息,但是小程序不能用window。
非实时通信备注:
uni.webview.1.5.6.js下载地址:https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.6.js
weixin-js-sdk安装版本:“weixin-js-sdk”: “^1.6.5”,
发送非实时信息关键代码:
<script type="text/javascript" src="static/js/uni.webview.1.5.6.js"></script>
"weixin-js-sdk": "^1.6.5",
<web-view :src="src" @message="getMessage" />
import wxH5 from "weixin-js-sdk";
wxH5.miniProgram.postMessage({ data: { action: 'test' } });