uniapp 打包 H5 实现在 uniapp 打包 APP 的 webview 通信

一、前言

遇到 uniapp 打包的 APP 在 webview 内嵌入 uniapp 打包的 H5 页面的需求,并实现通信。本篇主要总结了如何实现并总结遇到的问题,希望可以帮助大家减少负担。

实现需求主要有三个地方需要处理:

  1. index.html 的打包配置
  2. 导入 uni.webview.js
  3. 使用 myUni.getEnv() 导入和 myUni.webView.postMessage() 导出
二、index.html 的打包配置

直接拷贝覆盖 index.html 即可

<!DOCTYPE html>
<html lang="zh-CN"><head><meta charset="utf-8"><meta http-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 && typeof CSS.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><link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" /></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id="app"></div><!-- built files will be auto injected --><script type="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>');} else if (/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>');} else if (/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>');} else if (/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>');} else if (/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>');} else if (/quickapp/i.test(userAgent)) {// quickappdocument.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');}</script><!-- uni 的 SDK --><script type="text/javascript" src="<%= BASE_URL %>static/uni.webview.js"></script><script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script><script type="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

image-20240621095500277

在文件根目录下新建 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;function t(e,t){return n.call(e,t)}var i=[],a=function(e,n){var t={options:{timestamp:+new Date},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)throw new Error("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&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;a("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;a("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==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&&void 0!==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(new CustomEvent("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={});var E="undefined"!=typeof uni?uni:{};if(!E.navigateTo)for(var b in l)t(l,b)&&(E[b]=l[b]);return E.webView=l,E}));

打开 main.js 导入 uni.webview.1.5.2.js:

import App from './App'// #ifndef VUE3
import 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 = new Vue({...App
})
app.$mount()
// #endif// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {const app = createSSRApp(App)return {app}
}
// #endif
四、页面使用

webview 页面:

<template><view><web-view @message="message" :src="url"></web-view></view>
</template><script>export default {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>export default {data() {return {}},mounted() {let data = this.getQuery('data') // 获取页面信息console.log('data=============>>>>>>>>', JSON.parse(data));},methods: {//取url中的参数值getQuery(name) {// 正则:[找寻'&' + 'url参数名字' = '值' + '&']('&'可以不存在)let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");let r = window.location.search.substr(1).match(reg);console.log(r);if (r != null) {// 对参数值进行解码return decodeURIComponent(r[2]);}return null;},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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/31992.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

书生·浦语大模型LagentAgentLego智能体应用搭建 第二期

文章目录 智能体概述智能体的定义智能体组成智能体范式 环境配置Lagent&#xff1a;轻量级智能体框架实战Lagent Web Demo用 Lagent 自定义工具 AgentLego&#xff1a;组装智能体“乐高”直接使用AgentLego作为智能体工具使用 用 AgentLego 自定义工具 智能体概述 智能体的定义…

网络编程之XDP技术的基础eBPF

一、XDP和TC的技术支撑 在前面分析了XDP和TC技术&#xff0c;从它们的细节里可以看出&#xff0c;它们都在调用eBPF的钩子函数。那么eBPF是什么呢&#xff1f;在2021年曾经写过一篇《eBPF介绍》的初级文章&#xff0c;对eBPF做了一个入门级的普及。但是未曾在技术层面上进行展…

win制作git局域网仓库,克隆

仓库目录制作成共享文件 共享目录\USER-20230725LO 然后win使用git克隆\USER-20230725LO\git\wbrj

发布微信小程序需要icp证吗?

微信小程序需要办理ICP许可证吗&#xff1f; 微信小程序需不需要办理ICP许可证&#xff0c;具体要看你的小程序类目是什么&#xff0c;还要看你的小程序具体是做什么的&#xff1f; 根据《互联网信息服务管理办法》 第四条 国家对经营性互联网信息服务实行许可制度&#xff1b…

ffmpeg windows系统详细教程

视频做预览时黑屏&#xff0c;但有声音问题解决方案。 需要将 .mp4编成H.264格式的.mp4 一般上传视频的站点&#xff0c;如YouTube、Vimeo 等&#xff0c;通常会在用户上传视频时自动对视频进行转码&#xff0c;以确保视频能够在各种设备和网络条件下流畅播放。这些网站通常…

以10位明星为你献上的祝福视频为标题的科普介绍文章-华媒舍

祝福视频的意义和影响 祝福视频是指明星通过录制的视频&#xff0c;向观众表达美好的祝愿和关怀。这种视频以真挚的情感和鼓舞人心的话语&#xff0c;给人们带来了不同寻常的温暖和感动。由于明星的影响力和号召力&#xff0c;他们的祝福视频可以更广泛地传播&#xff0c;让更…

Android进阶:Bitmap的高效加载和Cache

二、Android中的缓存策略 缓存策略在Android中应用广泛。使用缓存可以节省流量、提高效率。 加载图片时&#xff0c;一般会从网络加载&#xff0c;然后缓存在存储设备上&#xff0c;这样下次就不用请求网络了。并且通常也会缓存一份到内存中&#xff0c;这样下次可以直接取内存…

C# 中的隐式和显式类型转换

当你需要转换值的类型时&#xff0c;可以使用类型转换。只有当你要转换的两种类型兼容时&#xff0c;才有可能。 当你收到错误“无法隐式将一种类型转换为另一种类型”时&#xff0c;说明你转换的两种类型不兼容。 int integer; // 声明一个名为 integer 的整型变量 integer …

项目启动 | 盘古信息助力鼎阳科技开启智能制造升级新征程

在全球数字化浪潮不断涌动的背景下&#xff0c;电子信息行业正迎来转型升级的关键阶段。近日&#xff0c;盘古信息与深圳市鼎阳科技股份有限公司&#xff08;简称“鼎阳科技”&#xff0c;股票代码&#xff1a;688112&#xff09;正式启动了IMS数字化智能制造工厂项目&#xff…

OpenFeign服务调用与负载均衡

目录 介绍使用高级特性超时控制重试机制默认HttpClient修改请求/响应报文压缩日志打印功能 相关文献 介绍 官网说明&#xff1a; Feign 是一个声明式 Web 服务客户端。它使编写 Web 服务客户端变得更加容易。要使用 Feign&#xff0c;请创建一个接口并对其进行注释。它具有可…

CSDN低质量分文章自动化获取

1. 背景 最近粉丝终于达到了5K&#xff0c;可是仍然无法通过优质作者申请&#xff0c;原来是平均质量分较低&#xff0c;优化了一些文章后分数提高仍然较慢&#xff0c;所以需要批量获取低质量文章&#xff0c;重点优化 2. 目标效果 3. 核心代码 其中的Cookie可以根据浏览器…

使用java +paho mqtt编写模拟发布温度及订阅的过程

启动mqtt 服务 创建项目&#xff0c;在项目中添加模块 添加文件夹 添加maven依赖 <dependencies><dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.0<…

如何下载和安装SQLynx数据库管理工具? (MySQL作为测试数据库)

目录 1. 官网下载 2. 安装软件 3. 启动SQLynx软件 4. 开始使用 5. 执行第一条SQL语句 6. 总结 SQLynx是一款先进的Web SQL集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为数据库管理、查询和数据分析设计。作为一个基于浏览器的工具&#xff08;同时也支持桌面…

Python xlwt库:写excel表格

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

基于java+springboot+vue实现的电商应用系统(文末源码+Lw)241

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本电商应用系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&a…

当flex-direction: column时,设置flex:1不生效解决办法

当需求是: 页面纵向排列,且最后一个元素撑满剩余高度 flex:1在横向排列时是可以的,但是纵向排列会失效,此时需要给最后一个子元素设置align-self: stretch;即可撑满剩余高度 <div class"father"><div class"child child1"></div><div…

Python抓取高考网图片

Python抓取高考网图片 一、项目介绍二、完整代码一、项目介绍 本次采集的目标是高考网(http://www.gaokao.com/gkpic/)的图片,实现图片自动下载。高考网主页如下图: 爬取的流程包括寻找数据接口,发送请求,解析图片链接,向图片链接发送请求获取数据,最后保存数据。 二…

C++设计模式——Composite组合模式

一&#xff0c;组合模式简介 真实世界中&#xff0c;像企业组织、文档、图形软件界面等案例&#xff0c;它们在结构上都是分层次的。将系统分层次的方式使得统一管理和添加不同子模块变得容易&#xff0c;在软件开发中&#xff0c;组合模式的设计思想和它们类似。 组合模式是…

DDP(Differential Dynamic Programming)算法举例

DDP(Differential Dynamic Programming)算法 基本原理 DDP(Differential Dynamic Programming)是一种用于求解非线性最优控制问题的递归算法。它基于动态规划的思想,通过线性化系统的动力学方程和二次近似代价函数,递归地优化控制策略。DDP的核心在于利用局部二次近似来…

(vue3)引入组件标红,...has no default export 组件没有默认导出

(vue3)引入组件标红&#xff0c;…has no default export 组件没有默认导出 一、项目背景&#xff1a; 创建的vitevue3ts项目页面有标红,但程序不报错 二、原因 由于之前安装了 Vetur 插件&#xff0c;Vetur 默认使用 eslint-plugin-vue&#xff0c;并且强制 export default …