目录
背景
因为本系统需要支持第三方系统页面的嵌入,于是尝试使用iframe标签,进行跨域通信,父子页面相互传值。
例如:想在www.baidu.com的页面中嵌入腾讯视频页面https://v.qq.com/,并且百度页面能像腾讯视频传输数据,或者腾讯视频能像百度发送数据。这时可以通过iframe的跨域通信方法,使用监听方式,监听嵌入页面传输的数据,达到联动效果。
方法
父页面向子页面传值:document.getElementById('myframe').contentWindow.postMessage('传输的数据',‘嵌入页面的url’)
子页面向父页面传值:window.parent.postMessage('传输的数据',‘父页面的url’)
监听传输信息的事件,父页面监听子页面数据,或者相反:
window.addEventListener('message',function(event){
console.log( "收到父页面" + event.origin + "消息:" + event.data+"随机数:"+Math.random(10000));
}
}, false);
应用
效果图
页面
准备两个页面
a.vue父页面,地址为http://localhost:9590/process/testForm。初始化时,父页面发送数据给子页面,需要在子页面加载完成后发送,不然接收不到数据。
<template>
<div >
<el-container>
<el-header class="header">
<el-button @click="sendWriteMessage">发送信息给子页面</el-button>
<el-input v-model="displayMessage" placeholder="接收子页面信息"/>
</el-header>
<el-main>
<el-tabs type="border-card">
<iframe
ref="myIframe"
id="myIframe"
name="myIframe"
:src="iframeForm.modelerUrl"
frameborder="0"
width="100%"
height="750px"
scrolling="auto"
></iframe>
</el-tabs>
</el-main>
</el-container>
</div>
</template>
<script>
export default {
name: 'testiframe',
components: {
},
props: {
},
data() {
return {
iframeForm:{
modelerUrl:'http://localhost:8080/custom-renderer',
modelVisible:true,
title:''
},
sendParentMessage:{
parentForm:'http://localhost:9590/process/testForm'
},
receiveMessage:{
url:'',
user:'',
action:'',
oper:'',
},
displayMessage:''
}
},
watch:{
},
computed: {
},
watch: {
},
mounted() {
},
created() {
this.sendWriteMessage()
let that = this
window.addEventListener('message', function(event){
console.log("收到" + event.origin + "消息:" + event.data+"消息:"+Math.random(10000));
if(event.data!== null&& event.data !== undefined)
{
that.displayMessage = event.data
that.receiveMessage = event.data
}
}, false);
},
methods: {
sendWriteMessage(){
let that = this
this.$nextTick(() => {
let iframe = that.$refs.myIframe
iframe.onload = function(){
let contentWindow = iframe.contentWindow
contentWindow.postMessage(JSON.stringify(that.sendParentMessage),that.iframeForm.modelerUrl)
}
iframe.contentWindow.postMessage(JSON.stringify(that.sendParentMessage),that.iframeForm.modelerUrl)
});
}
},
}
</script>
<style scoped>
</style>
b.vue子页面,地址为:http://localhost:8080/custom-renderer
<template>
<div class="containers" style="background-color:gray">
<el-button type="primary" @click="test">传值给父页面</el-button>
<input id="input" style="width:100%" value="111"/>
</div>
</template>
<script>
export default {
name: '',
components: {},
created() {
let that = this
window.addEventListener('message',function(event){//监听父页面传值,并赋值给输入框
console.log(event);
if(event.data !== null && event.data !== undefined )
{
that.receiveParentMessage = JSON.parse(event.data);
document.getElementById('input').value = "收到父页面" + event.origin + "消息:" + event.data+"随机数:"+Math.random(10000);
}
}, false);
},
// 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成,一般在该过程进行 Ajax 交互
mounted() {
},
data() {
return {
pack:{
url:'http://localhost:8080/custom-renderer',
user:'admin',
action:'write',
oper:'提交',
},
receiveParentMessage:{
action:'',
parentForm:''
},
show:true,
}
},
// 方法集合
methods: {
test(){//向父页面传值this.receiveParentMessage.parentForm='http://192.168.0.124:9590/process/testForm',当子页面加载完成后,由父页面传值过来。
window.parent.postMessage(JSON.stringify(this.pack), this.receiveParentMessage.parentForm)
},
},
// 计算属性
computed: {}
}
</script>
<style scoped>
</style>