描述:
小程序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' } });