uni-app webview的message監聽不生效(uni.postmessage is not a function)

uni-app開發app web-view組件message事件不觸發

  • 背景
  • 子頁面是h5(非uni-app版)
  • 子頁面是h5(uni-app版)

背景

大致背景是 在uni-app開發的客戶端app中使用web-view嵌入h5頁面,在h5中通過postmessage API觸發父組件web-view中的message事件

子頁面是h5(非uni-app版)

如果子組件是普通的h5版本,通過官方文檔示例可以實現消息通信
親測可用
在h5網頁中的添加uni-app的webview.js
在這里插入圖片描述

	<script type="text/javascript">!function (e, n) { "object" == typeof exports && "undefined" != typeof module ? module.exports = n() : "function" == typeof define && define.amd ? define(n) : (e = e || self).uni = n() }(this, (function () { "use strict"; try { var e = {}; Object.defineProperty(e, "passive", { get: function () { !0 } }), window.addEventListener("test-passive", null, e) } catch (e) { } var n = Object.prototype.hasOwnProperty; function i(e, i) { return n.call(e, i) } var t = []; function o() { return window.__dcloud_weex_postMessage || window.__dcloud_weex_ } function a() { return window.__uniapp_x_postMessage || window.__uniapp_x_ } var r = function (e, n) { var i = { options: { timestamp: +new Date }, name: e, arg: n }; if (a()) { if ("postMessage" === e) { var r = { data: n }; return window.__uniapp_x_postMessage ? window.__uniapp_x_postMessage(r) : window.__uniapp_x_.postMessage(JSON.stringify(r)) } var d = { type: "WEB_INVOKE_APPSERVICE", args: { data: i, webviewIds: t } }; window.__uniapp_x_postMessage ? window.__uniapp_x_postMessageToService(d) : window.__uniapp_x_.postMessageToService(JSON.stringify(d)) } else if (o()) { if ("postMessage" === e) { var s = { data: [n] }; return window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessage(s) : window.__dcloud_weex_.postMessage(JSON.stringify(s)) } var w = { type: "WEB_INVOKE_APPSERVICE", args: { data: i, webviewIds: t } }; window.__dcloud_weex_postMessage ? window.__dcloud_weex_postMessageToService(w) : window.__dcloud_weex_.postMessageToService(JSON.stringify(w)) } else { if (!window.plus) return window.parent.postMessage({ type: "WEB_INVOKE_APPSERVICE", data: i, pageId: "" }, "*"); if (0 === t.length) { var u = plus.webview.currentWebview(); if (!u) throw new Error("plus.webview.currentWebview() is undefined"); var g = u.parent(), v = ""; v = g ? g.id : u.id, t.push(v) } if (plus.webview.getWebviewById("__uniapp__service")) plus.webview.postMessageToUniNView({ type: "WEB_INVOKE_APPSERVICE", args: { data: i, webviewIds: t } }, "__uniapp__service"); else { var c = JSON.stringify(i); plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE", '",').concat(c, ",").concat(JSON.stringify(t), ");")) } } }, d = { navigateTo: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, n = e.url; r("navigateTo", { url: encodeURI(n) }) }, navigateBack: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, n = e.delta; r("navigateBack", { delta: parseInt(n) || 1 }) }, switchTab: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, n = e.url; r("switchTab", { url: encodeURI(n) }) }, reLaunch: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, n = e.url; r("reLaunch", { url: encodeURI(n) }) }, redirectTo: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}, n = e.url; r("redirectTo", { url: encodeURI(n) }) }, getEnv: function (e) { a() ? e({ uvue: !0 }) : o() ? e({ nvue: !0 }) : window.plus ? e({ plus: !0 }) : e({ h5: !0 }) }, postMessage: function () { var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {}; r("postMessage", e.data || {}) } }, s = /uni-app/i.test(navigator.userAgent), w = /Html5Plus/i.test(navigator.userAgent), u = /complete|loaded|interactive/; var g = window.my && navigator.userAgent.indexOf(["t", "n", "e", "i", "l", "C", "y", "a", "p", "i", "l", "A"].reverse().join("")) > -1; var v = window.swan && window.swan.webView && /swan/i.test(navigator.userAgent); var c = window.qq && window.qq.miniProgram && /QQ/i.test(navigator.userAgent) && /miniProgram/i.test(navigator.userAgent); var p = window.tt && window.tt.miniProgram && /toutiaomicroapp/i.test(navigator.userAgent); var _ = window.wx && window.wx.miniProgram && /micromessenger/i.test(navigator.userAgent) && /miniProgram/i.test(navigator.userAgent); var m = window.qa && /quickapp/i.test(navigator.userAgent); var f = window.ks && window.ks.miniProgram && /micromessenger/i.test(navigator.userAgent) && /miniProgram/i.test(navigator.userAgent); var l = window.tt && window.tt.miniProgram && /Lark|Feishu/i.test(navigator.userAgent); var E = window.jd && window.jd.miniProgram && /jdmp/i.test(navigator.userAgent); var x = window.xhs && window.xhs.miniProgram && /xhsminiapp/i.test(navigator.userAgent); for (var S, h = function () { window.UniAppJSBridge = !0, document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady", { bubbles: !0, cancelable: !0 })) }, y = [function (e) { if (s || w) return window.__uniapp_x_postMessage || window.__uniapp_x_ || window.__dcloud_weex_postMessage || window.__dcloud_weex_ ? document.addEventListener("DOMContentLoaded", e) : window.plus && u.test(document.readyState) ? setTimeout(e, 0) : document.addEventListener("plusready", e), d }, function (e) { if (_) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("WeixinJSBridgeReady", e), window.wx.miniProgram }, function (e) { if (c) return window.QQJSBridge && window.QQJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("QQJSBridgeReady", e), window.qq.miniProgram }, function (e) { if (g) { document.addEventListener("DOMContentLoaded", e); var n = window.my; return { navigateTo: n.navigateTo, navigateBack: n.navigateBack, switchTab: n.switchTab, reLaunch: n.reLaunch, redirectTo: n.redirectTo, postMessage: n.postMessage, getEnv: n.getEnv } } }, function (e) { if (v) return document.addEventListener("DOMContentLoaded", e), window.swan.webView }, function (e) { if (p) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram }, function (e) { if (m) { window.QaJSBridge && window.QaJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("QaJSBridgeReady", e); var n = window.qa; return { navigateTo: n.navigateTo, navigateBack: n.navigateBack, switchTab: n.switchTab, reLaunch: n.reLaunch, redirectTo: n.redirectTo, postMessage: n.postMessage, getEnv: n.getEnv } } }, function (e) { if (f) return window.WeixinJSBridge && window.WeixinJSBridge.invoke ? setTimeout(e, 0) : document.addEventListener("WeixinJSBridgeReady", e), window.ks.miniProgram }, function (e) { if (l) return document.addEventListener("DOMContentLoaded", e), window.tt.miniProgram }, function (e) { if (E) return window.JDJSBridgeReady && window.JDJSBridgeReady.invoke ? setTimeout(e, 0) : document.addEventListener("JDJSBridgeReady", e), window.jd.miniProgram }, function (e) { if (x) return window.xhs.miniProgram }, function (e) { return document.addEventListener("DOMContentLoaded", e), d }], M = 0; M < y.length && !(S = y[M](h)); M++); S || (S = {}); var P = "undefined" != typeof uni ? uni : {}; if (!P.navigateTo) for (var b in S) i(S, b) && (P[b] = S[b]); return P.webView = S, P }));
</script><script>document.addEventListener('UniAppJSBridgeReady', function () {console.log('可以打印一下uni.webView', uni.postMessage({data: {action: 'message'}}), '*')// uni.webView.navigateTo(...)});
</script>

引入webview.js后可以實現app的web-view和h5網頁的雙向數據通信。

子頁面是h5(uni-app版)

如果嵌入的h5是uni-app開發的,那么此處有個坑,uni-app默認是不提供uni.postmessage方法的,官方文檔說h5用window.postmessagewindow.parent.postmessage。但是很遺憾,親測不可用。但此時如果你像普通h5一樣在index.html引入webview.js后再去調用uni.postmessage 的話 在這里插入圖片描述
會發現系統報錯 uni.postmessage is not a function,經過幾小時的研究我得出結論大概率是webview.js引入的全局uni對象和uni-app框架自帶的全局uni對象沖突,導致uni.postmessage方法并沒有植入到uni對象中,并基于此結論找到了相關解決方案 傳送門

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917500.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917500.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917500.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【異常案例分析】使用空指針調用函數(非虛函數)時,沒有崩潰在函數調用處,而是崩在被調用函數內部

目錄 1、問題說明 2、代碼段地址與數據段地址 3、使用空指針調用BindWindow函數&#xff08;非虛函數&#xff09;&#xff0c;沒有崩在BindWindow函數的調用處&#xff0c;而是崩在函數內部 3.1、虛函數調用的二次尋址 3.2、崩潰在被調用函數內部 4、總結 C軟件異常排查…

鎖定中科院1區TOP!融合LSTM與Attention做時間序列預測 !

Transformer雖火&#xff0c;但在數據少、要求穩的時序預測場景中&#xff0c;LSTM仍是首選。尤其加上注意力機制后&#xff0c;更是彌補了LSTM的短板&#xff0c;增強了性能&#xff0c;實現了更精確的預測。這種組合不僅應用場景廣泛&#xff0c;工業界愛&#xff0c;學術界也…

在不可更改系統上構建數據響應機制的可選策略

在現代企業信息系統架構中&#xff0c;我們常常面臨如下挑戰&#xff1a;某個業務系統屬于“不可變更系統”&#xff0c;我們既不能修改其業務邏輯&#xff0c;也不能對其核心代碼做任何侵入式改動。但與此同時&#xff0c;我們又需要對該系統中的某些關鍵業務數據變更做出響應…

Docker 實戰 -- cloudbeaver

文章目錄前言文件目錄docker-compose.yml網絡連接前言 當你迷茫的時候&#xff0c;請點擊 Docker 實戰目錄 快速查看前面的技術文章&#xff0c;相信你總能找到前行的方向 上一篇文章 Docker 實戰 – Mysql 講述了用 docker 搭建 mysql 數據庫的過程, 連接數據庫的工具很多, …

Rust × WebAssembly 項目腳手架詳解

一、模板概覽 模板生成方式核心用途典型角色wasm-pack-templatecargo generate …把 Rust 代碼 打包成 npm 庫「底層算法/組件」作者create-wasm-appnpm init wasm-app構建純 JS/TS 項目&#xff0c;消費上面生成的 npm 包Web 前端/Node 服務rust-webpack-templatenpm init ru…

RSA 解密邏輯

以下是使用類的方式封裝 RSA 解密邏輯&#xff0c;使其更易于調用和管理&#xff1a; from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_v1_5 import base64 class RSADecryptor:"""RSA 解密工具類&#xff0c;封裝解密邏輯&#xff0c;方便…

Oracle 19C 在centos中安裝操作步驟和說明

1、oracle 一到五&#xff0c;是在centos下&#xff0c;搭建數據的每個具體詳細步驟。 oracle:一、環境準備-CSDN博客 oracle:二、centos下安裝oracle-CSDN博客 oracle :三、配置LISTEN-CSDN博客 oracle:四、創建數據庫-CSDN博客 oracle&#xff1a;五、配置修改-CSDN博客…

《前端無障礙設計的深層邏輯與實踐路徑》

一個Web應用的價值不僅在于其功能的豐富性,更在于它能否向所有用戶敞開大門。那些被忽略的交互細節—一段沒有替代文本的圖片、一個無法通過鍵盤觸發的按鈕、一組對比度不足的文字——正在悄然構建起一道無形的壁壘,將部分用戶隔絕在數字世界之外。前端無障礙設計(A11y)的本…

ctfshow-web入門-254-266-反序列化

web254 代碼審計&#xff0c;輸入給的username和password ?usernamexxxxxx&passwordxxxxxx web255 這題要從cookie中獲取值并且需要把isVip設為true&#xff0c;并且將序列化之后的結果進行url編碼 <?php class ctfShowUser{public $usernamexxxxxx;public $passw…

ssh服務器端口和本地端口映射

由于服務器防火墻設置&#xff0c;本地能ssh登錄遠程服務器&#xff0c;但本地不能通過http的方式訪問服務&#xff0c;如tensorborad、gradle或其他服務。在不需要修改防火墻安全設置的情況下&#xff0c;這里我們臨時通過ssh端口映射的方式&#xff0c;在本地瀏覽器訪問這些服…

計算機網絡——UDP

1. UDP的背景 1&#xff09;先有TCP&#xff0c;后覺笨重 在TCP被首次提出后&#xff0c;將“可靠傳輸&#xff0c;流量控制&#xff0c;擁塞控制”全做在一個協議里隨著應用增多 ——> 很多場景&#xff08;語音&#xff0c;視頻&#xff09;并不需要萬無一失 ——> 更…

常見的深度學習模塊/操作中的維度約定(系統性總結)

&#x1f7e9; 1. 數據張量&#xff08;特征圖&#xff09;維度這是我們喂進網絡或從網絡中出來的“實際數據”。類型維度格式舉例說明圖像/特征圖(B, C, H, W)(4, 3, 32, 32)PyTorch中最常用的數據布局&#xff08;NCHW&#xff09;圖像/特征圖&#xff08;TensorFlow風格&…

【筆記】重學單片機(51)(上)

為學習嵌入式做準備&#xff0c;重新拿起51單片機學習。此貼為學習筆記&#xff0c;僅記錄易忘點&#xff0c;實用理論基礎&#xff0c;并不是0基礎。 資料參考&#xff1a;清翔零基礎教你學51單片機 51單片機學習筆記1. C語言中的易忘點1.1 數據類型1.2 位運算符1.3 常用控制語…

Arrays.asList() add方法報錯java.lang.UnsupportedOperationException

1. 問題說明 記錄一下遇到的這個bug&#xff0c;下面是段個簡化后的問題重現代碼。 public class Test {public static void main(String[] args) {List<Integer> list Arrays.asList(1, 2, 3);list.add(4);} }2. 原因分析 我們看一下Arrays.asList(…) 的源碼&#xff…

克羅均線策略思路

一個基于移動平均線的交易策略&#xff0c;主要通過比較不同周期的移動平均線來生成買賣信號。該策略交易邏輯思路和特點&#xff1a;交易邏輯思路1. 多頭交易邏輯&#xff1a;- 當當前周期的收盤價高于其4周期移動平均線&#xff0c;并且4周期移動平均線高于9周期移動平均線&a…

Go語言--語法基礎7--函數定義與調用--自定義函數

函數是基本的代碼塊&#xff0c;用于執行一個任務。Go 語言最少有 1 個 main() 函數。你可以通過函數來劃分不同功能&#xff0c;邏輯上每個函數執行的是指定的任務。函數聲明告訴了編譯器函數的名稱、返回類型和參數。函數三要素名稱 》功能參數 》接口返回值 》結果函數分類內…

Ollama模型庫模型下載慢完美解決(全平臺)

前言在我們從ollama下載模型時,會發現ollama最開始下載速度很快,能達到10-20MB/s但到了后期,速度就會越來越慢,最終降低到10-20kb/s下載一個模型大多需要1到1.5小時這是因為ollama服務器負荷過大的問題思路如果在下載中終斷下載,在用ollama run恢復下載,速度就會又提上去,但3-4…

web:js的模塊導出/導入

一般web頁面中&#xff0c;html文件通過標簽script引用js文件。但是js文件之間的引用要通過import/exprot進行導入/導出&#xff0c;同時還要在html文件中對js文件的引用使用type屬性標注。在下面的例子中&#xff0c;html頁面<!DOCTYPE html> <html lang"en&quo…

關于Web前端安全防御之安全頭配置

一、核心安全頭的作用 1. X-Content-Type-Options: nosniff 該響應頭用于阻止瀏覽器對資源的 MIME 類型進行 “嗅探”&#xff08;猜測&#xff09;&#xff0c;強制瀏覽器嚴格遵守服務器返回的 Content-Type 頭部聲明。 風險背景&#xff1a; 瀏覽器默認會對未明確聲明類型…

C++ : 反向迭代器的模擬實現

一、reverse_iterator.h#pragma once namespace txf { //外界傳什么類型的iteator&#xff0c;它就用什么iterator 初始化 , list用_list_iterator<T,T&,,T*> ,vector<T> 用T*template<class Iterator,class Ref,class Ptr>//在這個反向迭代器中涉及到…