uniapp和webview之間的通信舉例詳解
1.背景
應(yīng)用使用了uniapp開(kāi)發(fā)跨端應(yīng)用,在uniapp中內(nèi)嵌webview頁(yè)面實(shí)現(xiàn)頁(yè)面熱更新效果,不需要用戶(hù)單獨(dú)重新安裝軟件即可實(shí)現(xiàn)頁(yè)面的版本更新。
2.webview通知uniapp
在開(kāi)發(fā)過(guò)程中我們難會(huì)遇到需要uniapp和webview來(lái)實(shí)現(xiàn)數(shù)據(jù)通信的場(chǎng)景,接下來(lái)介紹一種可行的uniapp和webview的數(shù)據(jù)通信方案。
在webview中我們可以使用當(dāng)前webview實(shí)例的postMessage方法來(lái)觸發(fā)webview組建的onPostMessage方法來(lái)傳遞數(shù)據(jù),重點(diǎn)就需要放在了如何將uniapp的webview實(shí)例來(lái)加入到webview的h5項(xiàng)目當(dāng)中。
uniapp官方文檔中指出可以使用uni.webview.js 這個(gè)js SDK 來(lái)將當(dāng)前的uni對(duì)象注入到webview所加載的H5項(xiàng)目當(dāng)中。
最新版地址:https://gitcode.net/dcloud/uni-app/-/raw/dev/dist/uni.webview.1.5.6.js;
1.UniAppJSBridgeReady :
這個(gè)是在引入webview的SDK之后,當(dāng)webview頁(yè)面被加載完成之后會(huì)觸發(fā),該事件觸發(fā)表示著uniapp和webview之間的橋成功搭建,uni對(duì)象被成功的注入到當(dāng)前H5的上下文中。
我們?cè)趇ndex.html文件中將SDK引入,這里的SDK引入必須放在body標(biāo)簽下面。
<!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 下載到自己的服務(wù)器 -->
<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('當(dāng)前環(huán)境:' + JSON.stringify(res));
});
// uni.webView.navigateTo(...)
});
</script>
</html>
2.webview中可用的uni API
| 方法名 | 說(shuō)明 | 平臺(tái)差異說(shuō)明 |
|---|---|---|
| uni.navigateTo | navigateTo | |
| uni.redirectTo | redirectTo | |
| uni.reLaunch | reLaunch | |
| uni.switchTab | switchTab | |
| uni.navigateBack | navigateBack | |
| uni.postMessage | 向應(yīng)用發(fā)送消息 | 抖音小程序不支持、H5 暫不支持(可以直接使用 window.postMessage |
| uni.getEnv | 獲取當(dāng)前環(huán)境 | 抖音小程序與飛書(shū)小程序不支持 |
3.發(fā)送消息
我們?cè)贖5中可以使用uni.postMessage方法來(lái)向應(yīng)用發(fā)送消息,應(yīng)用中的webview的onPostMessage方法會(huì)被觸發(fā),從而通過(guò)參數(shù)就可以拿到需要傳遞的數(shù)據(jù)。
或者因?yàn)榭梢允褂胾ni.webView獲取到當(dāng)前webview實(shí)例,調(diào)用實(shí)例postMessage方法也可以傳遞數(shù)據(jù)。
注意: 這種做法在H5端是不支持的,后續(xù)會(huì)介紹H5端的處理方式。
3.uniapp 通知webview
uniapp通知webview頁(yè)面,官方提供了一種巧妙地方式。在H5項(xiàng)目中全局暴露一個(gè)用于接收數(shù)據(jù)的函數(shù),然后在uniapp中去觸發(fā)這個(gè)函數(shù)將參數(shù)傳遞過(guò)去即可是實(shí)現(xiàn)數(shù)據(jù)的傳遞。
evalJS
uniapp為每一個(gè)webview組件實(shí)例掛載了一個(gè)evalJS方法,用于為webview頁(yè)面注入一個(gè)可執(zhí)行的js腳本代碼。這段代碼會(huì)在webview的全局作用域中執(zhí)行。我們使用evalJS來(lái)觸發(fā)一個(gè)特定的函數(shù),在H5的全局作用域中定義對(duì)應(yīng)的函數(shù),并提前寫(xiě)好對(duì)應(yīng)的數(shù)據(jù)處理邏輯。后續(xù)只需要在uniapp中觸發(fā)evalJS即可實(shí)現(xiàn)數(shù)據(jù)的傳遞。
注意:這種方式在H5端也是不支持的,后續(xù)會(huì)介紹。
4.H5中實(shí)現(xiàn)數(shù)據(jù)的通信
上述介紹的webview和uniapp的通信只針對(duì)于uniapp編譯的代碼是非H5環(huán)境,如果是H5環(huán)境則無(wú)效。因此使用postMessage 方案替代
postMessage
window.postMessage 是一個(gè)非常強(qiáng)大的 Web API,用于在不同窗口或內(nèi)嵌頁(yè)面(如 <iframe>)之間安全地傳遞消息。它允許跨源通信,即不同域名、協(xié)議或端口的頁(yè)面之間可以互相發(fā)送消息。
window.postMessage 方法允許一個(gè)窗口向另一個(gè)窗口發(fā)送消息。消息的接收方可以通過(guò)監(jiān)聽(tīng) message 事件來(lái)接收消息。為了確保安全性,postMessage 方法需要明確指定目標(biāo)窗口的來(lái)源(targetOrigin),以防止消息被發(fā)送到不安全的地址。
主頁(yè)面
<!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');
// 監(jiān)聽(tīng)按鈕點(diǎn)擊事件,向 iframe 發(fā)送消息
document.getElementById('sendMessage').addEventListener('click', () => {
// 確保 iframe 已加載完成
if (iframe.contentWindow) {
iframe.contentWindow.postMessage('Hello from main page!', 'https://other-origin.com');
}
});
// 監(jiān)聽(tīng)來(lái)自 iframe 的消息
window.addEventListener('message', (event) => {
// 驗(yàn)證來(lái)源
if (event.origin !== 'https://other-origin.com') return;
console.log('Received message from iframe:', event.data);
});
</script>
</body>
</html>
內(nèi)嵌頁(yè)面
<!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>
// 監(jiān)聽(tīng)按鈕點(diǎn)擊事件,向主頁(yè)面發(fā)送消息
document.getElementById('sendMessage').addEventListener('click', () => {
// 向父窗口發(fā)送消息
window.parent.postMessage('Hello from iframe!', '*');
});
// 監(jiān)聽(tīng)來(lái)自主頁(yè)面的消息
window.addEventListener('message', (event) => {
// 驗(yàn)證來(lái)源
if (event.origin !== 'http://main-page-origin.com') return;
console.log('Received message from main page:', event.data);
});
</script>
</body>
</html>總結(jié)
到此這篇關(guān)于uniapp和webview之間通信的文章就介紹到這了,更多相關(guān)uniapp和webview通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue利用sync語(yǔ)法糖實(shí)現(xiàn)modal彈框的項(xiàng)目實(shí)踐
本文主要介紹了vue利用sync語(yǔ)法糖實(shí)現(xiàn)modal彈框的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
解決Vue2.0自帶瀏覽器里無(wú)法打開(kāi)的原因(兼容處理)
本篇文章主要介紹了解決Vue2.0自帶瀏覽器里無(wú)法打開(kāi)的原因(兼容處理),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-07-07
解決vue多個(gè)路由共用一個(gè)頁(yè)面的問(wèn)題
下面小編就為大家分享一篇解決vue多個(gè)路由共用一個(gè)頁(yè)面的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
Vue模擬數(shù)據(jù),實(shí)現(xiàn)路由進(jìn)入商品詳情頁(yè)面的示例
今天小編就為大家分享一篇Vue模擬數(shù)據(jù),實(shí)現(xiàn)路由進(jìn)入商品詳情頁(yè)面的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
nuxt 每個(gè)頁(yè)面head標(biāo)簽內(nèi)容設(shè)置方式
這篇文章主要介紹了nuxt 每個(gè)頁(yè)面head標(biāo)簽內(nèi)容設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
vue+element項(xiàng)目實(shí)時(shí)監(jiān)聽(tīng)div寬度的變化
這篇文章主要介紹了vue+element項(xiàng)目里實(shí)時(shí)監(jiān)聽(tīng)某個(gè)div寬度的變化,然后執(zhí)行相應(yīng)的事件,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-08-08
vue3成功創(chuàng)建項(xiàng)目后?run?serve啟動(dòng)項(xiàng)目報(bào)錯(cuò)的解決
這篇文章主要介紹了vue3成功創(chuàng)建項(xiàng)目后?run?serve啟動(dòng)項(xiàng)目報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vue使用高德地圖根據(jù)坐標(biāo)定位點(diǎn)的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue使用高德地圖根據(jù)坐標(biāo)定位點(diǎn)的實(shí)現(xiàn)代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08

