一、前言
遇到 uniapp 打包的 APP 在 webview 内嵌入 uniapp 打包的 H5 页面的需求,并实现通信。本篇主要总结了如何实现并总结遇到的问题,希望可以帮助大家减少负担。
实现需求主要有三个地方需要处理:
- index.html 的打包配置
- 导入 uni.webview.js
- 使用 myUni.getEnv() 导入和 myUni.webView.postMessage() 导出
二、index.html 的打包配置
直接拷贝覆盖 index.html 即可
<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="utf-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><title>
<%= htmlWebpackPlugin.options.title %>
</title><!-- Open Graph data --><!-- <meta property="og:title" content="Title Here" /> --><!-- <meta property="og:url" content="http://www.example.com/" /> --><!-- <meta property="og:image" content="http://example.com/image.jpg" /> --><!-- <meta property="og:description" content="Description Here" /> --><script>var coverSupport ='CSS'in window &&typeofCSS.supports ==='function'&&(CSS.supports('top: env(a)')||CSS.supports('top: constant(a)'))
document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0'+(coverSupport ?', viewport-fit=cover':'')+'" />')</script><linkrel="stylesheet"href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css"/></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><divid="app"></div><!-- built files will be auto injected --><scripttype="text/javascript">var userAgent = navigator.userAgent;if(userAgent.indexOf('AlipayClient')>-1){// 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。
document.writeln('<script src="https://appx/web-view.min.js"'+'>'+'<'+'/'+'script>');}elseif(/QQ/i.test(userAgent)&&/miniProgram/i.test(userAgent)){// QQ 小程序
document.write('<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"><\/script>');}elseif(/miniProgram/i.test(userAgent)&&/micromessenger/i.test(userAgent)){// 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。
document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"><\/script>');}elseif(/toutiaomicroapp/i.test(userAgent)){// 头条小程序 JS-SDK 如果不需要兼容头条小程序,则无需引用此 JS 文件。
document.write('<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"><\/script>');}elseif(/swan/i.test(userAgent)){// 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。
document.write('<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"><\/script>');}elseif(/quickapp/i.test(userAgent)){// quickapp
document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');}</script><!-- uni 的 SDK --><scripttype="text/javascript"src="<%= BASE_URL %>static/uni.webview.js"></script><scripttype="text/javascript"src="https://unpkg.com/@dcloudio/[email protected]/index.js"></script><scripttype="text/javascript">// 待触发 `UniAppJSBridgeReady` 事件后,即可调用 uni 的 API。
document.addEventListener('UniAppJSBridgeReady',function(){
uni.postMessage({data:{action:'message'}});
uni.getEnv(function(res){
console.log('当前环境:'+JSON.stringify(res));});});
document.addEventListener('UniAppJSBridgeReady',function(){
console.log('UniAppJSBridgeReady');
webUni.getEnv(function(res){
console.log('当前环境:'+JSON.stringify(res));});});</script></body></html>
三、导入 uni.webview.js
在文件根目录下新建 utils 目录,新建 uni.webview.1.5.2.js ,拷贝代码导入:
!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;functiont(e,t){returnn.call(e,t)}var i=[],a=function(e,n){var t={options:{timestamp:+newDate},name:e,arg:n};if(window.__dcloud_weex_postMessage||window.__dcloud_weex_){if("postMessage"===e){var a={data:[n]};return window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessage(a):window.__dcloud_weex_.postMessage(JSON.stringify(a))}var o={type:"WEB_INVOKE_APPSERVICE",args:{data:t,webviewIds:i}};window.__dcloud_weex_postMessage?window.__dcloud_weex_postMessageToService(o):window.__dcloud_weex_.postMessageToService(JSON.stringify(o))}if(!window.plus)return window.parent.postMessage({type:"WEB_INVOKE_APPSERVICE",data:t,pageId:""},"*");if(0===i.length){var r=plus.webview.currentWebview();if(!r)thrownewError("plus.webview.currentWebview() is undefined");var d=r.parent(),s="";s=d?d.id:r.id,i.push(s)}if(plus.webview.getWebviewById("__uniapp__service"))plus.webview.postMessageToUniNView({type:"WEB_INVOKE_APPSERVICE",args:{data:t,webviewIds:i}},"__uniapp__service");else{var w=JSON.stringify(t);plus.webview.getLaunchWebview().evalJS('UniPlusBridge.subscribeHandler("'.concat("WEB_INVOKE_APPSERVICE",'",').concat(w,",").concat(JSON.stringify(i),");"))}},o={navigateTo:function(){var e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{},n=e.url;a("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{},n=e.delta;a("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{},n=e.url;a("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{},n=e.url;a("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{},n=e.url;a("redirectTo",{url:encodeURI(n)})},getEnv:function(e){window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void0!==arguments[0]?arguments[0]:{};a("postMessage",e.data||{})}},r=/uni-app/i.test(navigator.userAgent),d=/Html5Plus/i.test(navigator.userAgent),s=/complete|loaded|interactive/;var w=window.my&&navigator.userAgent.indexOf("AlipayClient")>-1;var u=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 g=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var v=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);for(var l,_=function(){window.UniAppJSBridge=!0,document.dispatchEvent(newCustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},f=[function(e){if(r||d)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&s.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),o},function(e){if(v)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(w){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(u)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){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){return document.addEventListener("DOMContentLoaded",e),o}],m=0;m<f.length&&!(l=f[m](_));m++);l||(l={});varE="undefined"!=typeof uni?uni:{};if(!E.navigateTo)for(var b in l)t(l,b)&&(E[b]=l[b]);returnE.webView=l,E}));
打开 main.js 导入 uni.webview.1.5.2.js:
import App from'./App'// #ifndef VUE3import Vue from'vue'import'./uni.promisify.adaptor'// ***************************** 导入 ***************************** //import*as uni from'./utils/uni.webview.1.5.2.js'
document.addEventListener("UniAppJSBridgeReady",function(){// 这里必须更换uni,不然指向有误Vue.prototype.myUni = uni
});// *************************************************************** //
Vue.config.productionTip =false
App.mpType ='app'const app =newVue({...App
})
app.$mount()// #endif// #ifdef VUE3import{ createSSRApp }from'vue'exportfunctioncreateApp(){const app =createSSRApp(App)return{
app
}}// #endif
四、页面使用
webview 页面:
<template><view><web-view @message="message":src="url"></web-view></view></template><script>exportdefault{data(){return{url:'http://XXX.XXX.X.XXX:XXXX/?data='};},onLoad(){let data =[{name:'测试数据'}]this.url +=encodeURIComponent(JSON.stringify(data))},methods:{// 在小程序中没办法这样轻松获取数据,只有在离开页面、转发、销毁等情况下才可以获取,十分离谱message(arg){// 获取 H5 提交参数
console.log(arg)},}};</script>
H5 页面
<template><view @click="sendMessage()"></view></template><script>exportdefault{data(){return{}},mounted(){let data =this.getQuery('data')// 获取页面信息
console.log('data=============>>>>>>>>',JSON.parse(data));},methods:{//取url中的参数值getQuery(name){// 正则:[找寻'&' + 'url参数名字' = '值' + '&']('&'可以不存在)let reg =newRegExp("(^|&)"+ name +"=([^&]*)(&|$)");let r = window.location.search.substr(1).match(reg);
console.log(r);if(r !=null){// 对参数值进行解码returndecodeURIComponent(r[2]);}returnnull;},sendMessage(){// 提交参数let that =this;this.myUni.webView.postMessage({// 提交参数一定要放在data内data:{id:0,text:'Id'},});},}}</script>
五、参考
webview使用uniapp项目开发无法使用uni.postMessage(踩坑经验分享) - DCloud问答
uniapp使用webview嵌入vue页面及通信_uniapp webview页面和嵌入的子页面通信-CSDN博客
如何在uniapp中优雅地使用WebView - 林恒 - 博客园 (cnblogs.com)
web-view | uni-app官网 (dcloud.net.cn)
如何在uniapp中优雅地使用WebView - 林恒 - 博客园 (cnblogs.com)
web-view | uni-app官网 (dcloud.net.cn)
uni-app和web-view页面相互传参_uniapp webview传参-CSDN博客
版权归原作者 Brod_Roy 所有, 如有侵权,请联系我们删除。