一、 背景
一个项目为vue2,一个项目为vue3,两个不同的项目实现iframe嵌入,并实现通信
二、方案
iframe跨域时,iframe组件之间常用的通信,主要是H5的possmessage方法
三、案例代码
父页面-vue2(端口号为127.0.0.1:8080)
<template>
<div>
<div class="container">
<iframe
ref="iframeId"
id="iframeId"
src="http://127.0.0.1:8081"
frameborder="0"
border="0"
hspace="0"
vspace="0"
scrolling="yes"
height="100%"
width="100%"
></iframe>
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
@Component({
components: {},
})
export default class FeatureService extends Vue {
// 定义一个方法,用于发送消息到iframe
private postMessageToIframe() {
// 设置延时,确保iframe已经加载完成
setTimeout(() => {
// 定义要发送的数据
const iframeInfo = { isIframeParent: true };
// 定义目标源
const targetOrigin = 'http://127.0.0.1:8081';
// 获取iframe引用
const iframe = this.$refs.iframeId;
// 向iframe发送消息
iframe.contentWindow.postMessage(
JSON.stringify(iframeInfo),
targetOrigin
);
}, 500);
}
private mounted() {
// 在组件挂载后,发送消息到iframe
this.postMessageToIframe();
window.addEventListener('message', this.handleMessage, false);
}
private handleMessage(event: MessageEvent) {
// 通过origin对消息进行过滤,避免遭到XSS攻击
if (event.origin === 'http://127.0.0.1:8081') {
console.log('子页面传输过来参数', event.data);
}
}
}
</script>
<style lang="less" scoped>
.container {
width: 100%;
margin-top: -40px;
height: 100vh;
overflow: hidden;
#iframeId {
width: 100%;
display: block;
}
}
</style>
子页面-vue3, (端口号为127.0.0.1:8081)
<template>
<div>
<!-- 顶部导航 -->
<TopMenu v-if="!iframeParentInfo.isIframeParent" />
<div class="demo-sidebar-container demo-full-width">
<!-- 侧边栏 -->
<SiderBar v-if="!iframeParentInfo.isIframeParent" />
<!-- 内容容器 -->
<ContentBox />
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue'
const iframeParentInfo = ref({})
const messageHandler = (e) => {
// 通过origin对消息进行过滤,避免遭到XSS攻击
if (e.origin !== 'http://127.0.0.1:8080') return
if (typeof e.data === 'string') {
parseData(e.data)
}
}
const parseData = (data) => {
try {
iframeParentInfo.value = JSON.parse(data)
console.log('父页面传输过来参数', data)
} catch (error) {
console.error('解析JSON出错', error)
iframeParentInfo.value = {}
}
}
onMounted(() => {
// 获取 父向 子(iframe) 传递的信息
window.addEventListener('message', messageHandler)
// 子(iframe)向父传递信息
window.parent.postMessage('Hello Parent!', '*')
})
</script>