实现webView和⼩程序通讯,webView和iframe通讯,⽽后以
webView作为。。。
之前领导要求就打通webView、⼩程序和iframs三者之间的通讯做⼀份技术⽂档说明,功能是做出来了,结果后⾯没有接到那个项⽬,也就没有继续开发下去,但也值得记录⼀下。
项⽬⽬标
实现webView和⼩程序通讯,webView和iframe通讯,⽽后以webView作为中转站,实现webView中的iframe和⼩程序通讯。
需求确定
在商城⼩程序中以webView的形式引⼊客服聊天页⾯IM,在IM中以iframe的形式嵌⼊第三⽅页⾯,内容和样式第三⽅⾃定义。iframe的操作需求整理如下:
1. 跳转到⽂章详情
2. 链接到另⼀个客服
3. 跳转到商品详情
4. 跳转到商品购物车页
5. 跳转到订单详情
6. 发送消息
可以整理为三⼤类:1.⼩程序页⾯跳转2.向某⼀个客服发起会话3.在当前会话发送消息
实现
1. webView和⼩程序通讯
官⽅⽂档对于web-view组件的描述是:承载⽹页的容器。会⾃动铺满整个⼩程序页⾯,个⼈类型的⼩程序暂不⽀持使⽤。所以在⼩程序中webView是不能以弹窗的形式或者占据页⾯⼀部分和其它内容共存,这个特点⼩程序和⽀付宝⼩程序都具备。
webView组件和⼩程序只能通过bindmessage事件绑定进⾏通讯,对于这个事件官⽅的描述是这样的:⽹页向⼩程序 postMessage 时,会在特定时机(⼩程序后退、组件销毁、分享)触发并收到消息。也
就是说⽆论webView通过postMessage向⼩程序发送多少次消息,只要不是在特定的时机(⼩程序后退、组件销毁、分享),⼩程序就不会收到webView的消息。
通过以上两点,我们可以确定⼩程序的当前页⾯只有⼀个webView是有效内容,那⼩程序和webView之间的通讯最常⽤的也就是⼩程序进⾏页⾯的跳转了。
// 在webView页⾯中引⼊JS⽂件
<script src="res.wx.qq/open/js/jweixin-1.3.2.js"></script>
// 进⾏页⾯跳转
iframe参数传递wx.miniProgram.navigateTo({
url: '/pages/home2/index', // ⼩程序页⾯路径
})
2. webView和内嵌的iframe页⾯通讯
两者通过postMessage进⾏通讯,主要代码如下
window.addEventListener('message', (event) => {
if (window.parent !== event.source) { return }
console.log(event, 'event'); //接收到的信息
top.postMessage("发送给⽗级页⾯的信息,可以为对象", '⽗级页⾯url或者*');
}, false);
完整主要代码
1. ⼩程序
<WebView src="xxxx"></WebView>
2. webView客服聊天页⾯IM
// 在webView页⾯中引⼊JS⽂件
<script src="res.wx.qq/open/js/jweixin-1.3.2.js"></script>
let ua = LowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
//ios的ua中⽆miniProgram,但都有MicroMessenger(表⽰是浏览器)
Env((res) => {
if (res.miniprogram) {
console.log("在⼩程序⾥");
// 接收到消息
window.addEventListener('message', this.fnTest, false);
} else {
console.log("不在⼩程序⾥");
}
})
} else {
console.log('不在⾥');
}
fnTest = (event) => {
let data = event.data;
if (data.operation === 'msg') {
// 在当前会话发送消息
let r = il(Math.random() * 100000)
let uuid = berId + w() + r;
let sendData = '';
/
/ 0视频,1图⽚,2⽂件,4⽂本,8富⽂本,103iframe
switch (pe) {
// 消息类型处理
case 103:
sendData = data.data.iframeUrl;
break;
}
// this.sendMessage IM中发送消息函数
this.sendMessage(sendData, pe, uuid);
} else if (data.operation === 'action') {
// ⼩程序页⾯跳转
wx.miniProgram.navigateTo({
url: data.data.url //'/pages/home2/index'
})
} else if (data.operation === 'chat') {
let code = QueryString('code')
let url = `index.html?code=${code}&otherId=7&sessionScope=1&userCode=${data.data.userCode}` // 向某⼀个客服发起会话
uter.push(url)
}
}
3. 第三⽅iframe页⾯
<!-- 简单的模拟html页⾯ -->
<span class="btn" >发送消息</span>
<span class="action" >跳转页⾯</span>
<span class="chat" >跟他聊聊</span>
window.addEventListener('message', (event) => {
if (window.parent !== event.source) { return }
console.log(event, 'event'); //接收到的信息
top.postMessage("发送给⽗级页⾯的信息,可以为对象", '⽗级页⾯url或者*');
}, false);
// operation 操作类型string msg:发送消息,action:跳转页⾯,chat:发起聊天
// type 消息类型string operation为msg时,0视频,1图⽚,2⽂件,4⽂本,8富⽂本,103iframe
// 其他具体参数另定
$('.btn').on('click', function () {
top.postMessage({
operation: 'msg',
data: {
data: '消息内容',
type: 103, //Number类型
size: 110, //Number类型
name: '', //⽂件名称
iframeUrl: 'dev.iservice.dtyunxi/i-service/dev/iservice-customer-web-pc/test.html'
},
}, '*')
});
$('.action').on('click', function () {
top.postMessage({
operation: 'action',
data: {
url: '/pages/home2/index?xxx=xx', // 需要跳转页⾯
}
}, '*')
});
$('.chat').on('click', function () {
top.postMessage({
operation: 'chat',
data: {
userCode: '007', // 客服⼯号
}
}, '*')
});
定义参数
参数名类型是否必填描述
operation string是枚举值:1. msg:发送消息 2.action:跳转页⾯ 3.chat:发起聊天
data object是
data参数
参数名类型是否必填描述
type number operation为msg时必填0视频,1图⽚,2⽂件,4⽂本,8富⽂本,103iframe
size number type为2时必填⽂件⼤⼩,默认为0
name string type为2时必填⽂件名称,默认为空
iframeUrl string type为103时必填iframe路径
data string operation为msg且type不为103时必填type为0,1,2时,为视频、图⽚、⽂件的路径,type为4,8时,为发送的内容url string operation为action时必填⼩程序跳转路径
userCode string operation为chat时必填客服⼯号
⽀付宝⼩程序
⼩程序代码
// .axml
<view class="page">
<web-view src="xxxx" onMessage="onmessage"></web-view>
</view>
// .js
Page({
onmessage(e){
// 拿到webView数据,进⾏⼀系列事件处理
console.log(e,'e')
}
});
webView代码
// 引⼊js
<script type="text/javascript" src="appx/web-view.min.js"></script>
<!-- 如该 H5 页⾯需要同时在⾮⽀付宝客户端内使⽤,为避免该请求404,可参考以下写法 -->
<!-- 请尽量在 html 头部执⾏以下脚本 -->
<script>
if (navigator.userAgent.indexOf('AlipayClient') > -1) {
document.writeln('<script src="appx/web-view.min.js"' + '>' + '<' + '/' + 'script>');
}
</script>
componentWillUnmount() {
// 离开页⾯,清除监听
}
fnTest = (event) => {
// alert(JSON.stringify(event), 'event')
let data = event.data;
if (data.operation === 'msg') {
// 在当前会话发送消息
let r = il(Math.random() * 100000)
let uuid = berId + w() + r;
let sendData = '';
// 0视频,1图⽚,2⽂件,4⽂本,8富⽂本,103iframe
switch (pe) {
/
/ 消息类型处理
case 103:
sendData = data.data.iframeUrl;
break;
}
// this.sendMessage IM中发送消息函数
this.sendMessage(sendData, pe, uuid);
} else if (data.operation === 'action') {
// ⼩程序页⾯跳转
// my.navigateTo({ url: `../../${data.data.url}` });
my.navigateTo({ url: `../test/test` });
} else if (data.operation === 'chat') {
let code = QueryString('code')
let url = `index.html?code=${code}&otherId=7&sessionScope=1&userCode=${data.data.userCode}`
// 向某⼀个客服发起会话
uter.push(url)
}
}
componentDidMount() {
window.addEventListener('message', this.fnTest, false);
}
特别说明:webView向⽀付宝⼩程序发送消息时,并没有⼩程序接收webView消息的限制【需要在
特定时机(⼩程序后退、组件销毁、分享)触发才能收到消息】,只要webView通过my.postMessage(obj)向⼩程序发送消息,⼩程序就能接收到消息,⽀付宝⼩程序和webView的通讯更⽅便灵活。
流程图
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论