当前位置: 首页 > news >正文

【web-view加载h5】uniapp中使用web-view相互通信+uniapp向webview中实时通信

相关知识点:
【web-view加载h5】小程序中web-view加载uni-app H5如何使用postMessage方法的解决方案

【web-view加载h5】uniapp中使用web-view相互通信+uniapp向webview中实时通信

一、概要

  1. uniapp打包成的小程序、app,在某些场景下需要访问第三方或其他上线的h5页面,并要实现交互通信,一般就是h5页面点击某个按钮,需要通知应用做出下一步的操作。
  2. 注意:根据官方文档提供的例子,APP、微信小程序、H5都没问题,但是百度小程序必须添加业务域名通信功能才能生效。
  3. 下面的代码还实现了应用向h5页面即时通讯,关键词:‘#’。
  4. h5中获取小程序或父级传递的参数参考该文章的第三点:【web-view加载h5】小程序中web-view加载uni-app H5如何使用postMessage方法的解决方案

二、uniapp页面

<template>
	<view>
		<web-view src="http://lp.demo.com/" @message="handleMessage"></web-view>
	</view>
</template>

<script>
	export default {
		data() {
			return {

			}
		},
		methods: {
			handleMessage(evt) {
				console.log('接收到的消息:' ,evt.detail.data[0].action);
				uni.showModal({
					content:JSON.stringify(evt.detail.data)
				})
				if(evt.detail.data[0].action=='back'){
					uni.navigateBack({
						delta:1
					})
				}
			}
		}
	}
</script>

<style>

</style>

三、h5页面

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<meta name="viewport"
		content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<title>网络网页</title>
	<style type="text/css">
		.btn {
			display: block;
			margin: 20px auto;
			padding: 5px;
			background-color: #007aff;
			border: 0;
			color: #ffffff;
			height: 40px;
			width: 200px;
		}

		.btn-red {
			background-color: #dd524d;
		}

		.btn-yellow {
			background-color: #f0ad4e;
		}

		.desc {
			padding: 10px;
			color: #999999;
		}

		.post-message-section {
			visibility: hidden;
		}
	</style>
</head>

<body>
	<p class="desc">web-view 组件加载网络 html 示例。点击下列按钮,跳转至其它页面。</p>
	<div class="btn-list">
		<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
		<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
		<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
		<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
		<button class="btn" type="button" data-action="switchTab">switchTab</button>
	</div>
	<div class="post-message-section">
		<p class="desc">网页向应用发送消息,注意:小程序端应用会在此页面后退时接收到消息。</p>
		<div class="btn-list">
			<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
		</div>
	</div>
	<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.22.js"><\/script>');
		} else if (/quickapp/i.test(userAgent)) {
			// quickapp
			document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');
		}
		if (!/toutiaomicroapp/i.test(userAgent)) {
			document.querySelector('.post-message-section').style.visibility = 'visible';
		}
	</script>
	<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.22.js"></script>
	<!-- uni 的 SDK -->
	<script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.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.querySelector('.btn-list').addEventListener('click', function (evt) {
				var target = evt.target;
				if (target.tagName === 'BUTTON') {
					var action = target.getAttribute('data-action');
					switch (action) {
						case 'switchTab':
							uni.switchTab({
								url: '/pages/index/index'
							});
							break;
						case 'reLaunch':
							uni.reLaunch({
								url: '/pages/index/index'
							});
							break;
						case 'navigateBack':
							uni.navigateBack({
								delta: 1
							});
							break;
						case 'navigateTo':
							uni.navigateTo({
								url: '/pages/center/center'
							});
							break;
						case 'redirectTo':
							uni.redirectTo({
								url: '/pages/center/center'
							});
							break;
						default:
							uni[action]({
								url: '/pages/index/index'
							});
							break;
					}
				}
			});
			document.getElementById('postMessage').addEventListener('click', function () {
				console.log('通信消息', uni)
				uni.postMessage({
					data: {
						action: 'back'
					}
				});
			});
		});
	</script>
</body>
</html>

参考:https://uniapp.dcloud.io/component/web-view


四、uniapp向webview中实时通信

其中之一就是小程序不能向内置的webview实时传参,因为只能通过url地址首次传递数过去。官方不开放接口看起来无可奈何。

但是世上无难事儿,只怕有心人,作为一个合格的程序员就应该是一个有心人。不废话:诀窍就是通过url地址传递参数给webview。但是问题来了,动态的参数会使webview重新加载页面,页面一刷新,一切都白搭。但是的但是,小程序也有漏洞,千防万防就是防不住我呀,url地址不是有“锚”连接吗(“#”),对,就是这个符号。在url地址里面添加这个符号,后面紧跟动态参数,比如:http://p.vr100.com/index.php?m=bbs#1,这样webview地址就不会重新加载,参数1也过去了,然后在h5页面里面获取url地址,完美解决!

h5中:

<script type="text/javascript">
	var getUrlData = {
		callback: null,
		_t: 0,
		init(fn) {
			this.callback = fn;
			this.bind();
			this.change.call(this);
		},
		bind() {
			let that = this;
			if (("onhashchange" in window) && ((typeof document.documentMode === "undefined") || document.documentMode == 8)) {
				window.onhashchange = () => {
					that.change.call(that);
				};
			} else {
				clearInterval(this._t);
				this._t = setInterval(() => {
					that.change.call(that);
				}, 150);
			}
		},
		change() {
			let that = this,
				_hash = window.location.hash,
				_data = null;
			try {
				_data = JSON.parse(decodeURIComponent(_hash.split('#')[1]));
			} catch (e) {
				_data = decodeURIComponent(_hash.split('#')[1]);
			}
			if (that.callback) that.callback({
				type: that.getQuery('type'),
				data: _data
			});
		},
		getQuery(name) {
			let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
			let r = decodeURIComponent(window.location.search).substr(1).match(reg);
			if (r != null) {
				// 对参数值进行解码
				return decodeURIComponent(r[2]);
			}
			return null;
		}
	}
</script>

使用:

getUrlData.init(function(res){
	console.log(res);//返回的格式例如 {type: 'myType', data: 1}
})

效果:

image

需要注意的点:

图中的这个type名称可以根据自己的需求更改,需要什么就改什么!
image

相关文章:

  • 天天团购--源码目录结构
  • uniapp之安卓APP权限说明
  • easyui datagrid使用
  • 全局弹窗:uniapp之app可覆盖原生组件的全局调用弹窗
  • Caused by: Unable to locate parent package [json-package] for [class com.you.action.ColumnAction] -
  • 防抖和节流的理解
  • switch中的break和return的区别
  • 测试Js权限
  • uniapp开发:uni.request基于async+await的二次封装,兼容vue2、vue3、及多端
  • 自定义Property属性动画
  • 阿里iconfont图标ttf转换为base64【非常详细】
  • 浏览器输入url以后所经历的过程
  • linux中DNS原理详解
  • 原型链的简单理解【关系到结论】
  • Qt中实现渐变动画效果
  • JavaScript-如何实现克隆(clone)函数
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 【翻译】babel对TC39装饰器草案的实现
  • 2018一半小结一波
  • Android 架构优化~MVP 架构改造
  • AngularJS指令开发(1)——参数详解
  • CAP理论的例子讲解
  • ECMAScript入门(七)--Module语法
  • Git 使用集
  • Hibernate最全面试题
  • JAVA_NIO系列——Channel和Buffer详解
  • Javascripit类型转换比较那点事儿,双等号(==)
  • javascript 总结(常用工具类的封装)
  • Java-详解HashMap
  • python 装饰器(一)
  • Redis在Web项目中的应用与实践
  • SegmentFault 2015 Top Rank
  • 关于 Cirru Editor 存储格式
  • 汉诺塔算法
  • 记一次用 NodeJs 实现模拟登录的思路
  • nb
  • 看到一个关于网页设计的文章分享过来!大家看看!
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #{}和${}的区别?
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (Note)C++中的继承方式
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • ... 是什么 ?... 有什么用处?
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • @html.ActionLink的几种参数格式
  • @RunWith注解作用
  • [ vulhub漏洞复现篇 ] Hadoop-yarn-RPC 未授权访问漏洞复现
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [ARM]ldr 和 adr 伪指令的区别