vue3 与 html文件 通讯
postMessage方法传递
postMessage方法是HTML5中提供的一种跨文档通信的方式,可以在不同的窗口或者iframe之间传递数据。
<template>
<button @click="vueSendMsg">vue向iframe传递信息</button>
<iframe
:src="iframeUrl"
frameborder="0"
ref="iframeDom"
style="width: 100vw; height: 100vh"
></iframe>
</template>
<script lang="ts">
import { ref,reactive, defineComponent, onMounted, computed } from "vue";
export default defineComponent({
name: "IframeComponent",
setup(props) {
const iframeUrl = computed(() => {
const url = "/public/static/index.html";
return url;
});
const data = reactive({
des: "传递的数据"
});
const iframeDom = ref();
const vueSendMsg = () => {
const iframeWindow = iframeDom.value.contentWindow;
iframeWindow.postMessage(JSON.stringify(data), "*");
};
const receiveChild = (e) => {
if(e.data.type == "jsonData"){//
console.log(e.data.jsonData,'接收到了数据')
}
};
onMounted(() => {
// 获取子页面传输数据
window.addEventListener("message", receiveChild);
});
return {
iframeUrl,
vueSendMsg,
iframeDom
};
}
});
</script>
<style lang="scss" scoped>
.iframe-dom {
width: 100%;
height: 100%;
border: 0;
}
</style>
vue2组件
<template>
<div class="home">
<button @click="sendMsgToParent">测试给父组件发布数据</button>
<span>{{ parentData }}</span>
</div>
</template>
<script>
export default {
name: 'HomeView',
components: {
},
data () {
return {
parentData: '父组件数据',
data: {
jsonData: '测试json数据',
type: 'jsonData'
}
}
},
methods: {
handleMessageFromParent (event) {
let data = {}
console.log('收到父页面消息', event)
console.log('数据格式', typeof event.data)
if (typeof event.data === 'string') {
data = JSON.parse(event.data)
}
if (data?.type === 'initData') {
this.parentData = data?.des
}
},
sendMsgToParent () {
// 给父页面发送消息
window.parent.postMessage(
this.data,
'*'
)
}
},
mounted () {
// 监听父页面发送过来的消息
window.addEventListener('message', this.handleMessageFromParent)
}
}
</script>
html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>💗</title>
<style> </style>
</head>
<body>
<button id="left_test" title="测试给父组件发布数据"><i class="layui-icon layui-icon-set">测试给父组件发布数据</i></button>
<script class="iframe">
window.onload = function () {
// 接收父页面传参
window.addEventListener('message', (event) => {
let data = JSON.parse(event.data)
console.log(data)
});
};
document.getElementById("left_test").addEventListener("click", function (event) {
let data = {
jsonData: '测试json数据',
type: 'jsonData'
}
// 传参
window.parent.postMessage(data, '*')
});
</script>
</body>
</html>
postMessage()使用
postMessage()
是 JavaScript 中一个用于在不同窗口、iframe 或者标签页之间进行跨域通信的 API。它通过一种安全的方式允许文档之间发送消息,而不要求它们在同一个源(域名、协议、端口)上
window.postMessage(message, targetOrigin, [transfer])
-
message:要发送的消息,可以是字符串或是任何可序列化的数据(例如对象、数组)。消息内容会通过结构化克隆算法进行传递,类似 JSON 序列化。
-
targetOrigin:指定可以接收消息的窗口的源(协议、域名、端口),以确保消息不会被发送到未知或不信任的站点。可以使用 "*" 表示不限制目标源,但这样可能会带来安全隐患。
-
transfer(可选):传递的对象,通常是像 ArrayBuffer 或者 MessagePort 这样的对象,这些对象会通过转移的方式而不是拷贝传递。
iframe 与主页面通信
跨窗口通信
//父窗口发送消息给子窗口 const popup = window.open("https://other-page.com"); popup.postMessage('Hello 子窗口', 'https://other-page.com'); //子窗口接收消息 window.addEventListener('message', function(event) { if (event.origin === 'https://other-page.com') { console.log('Message from 父窗口:', event.data); } });
Web Workers 与主线程通信
//主线程发送消息给 Web Worker const worker = new Worker('worker.js'); worker.postMessage('Hello Worker');
// worker.js self.addEventListener('message', function(event) { console.log('Message from 主线程:', event.data); });
Service Worker 与页面通信
event 对象的属性
目标窗口接收到
message
事件- data:发送的消息内容。
- origin:消息来源的协议、域名和端口。
- source:发送消息的窗口对象,允许我们回复发送方。
- lastEventId:消息的唯一标识符(通常在服务器发送事件中使用)。
- ports:如果消息涉及 MessagePort 对象,则可以通过此属性获取传递的端口。