iframeWindow.contentWindow.postMessage 是 JavaScript 里用于实现跨窗口通信的重要方法,常被用于解决不同窗口或 iframe 之间的通信问题,特别是在跨域场景下。
postMessage 方法允许一个窗口安全地向另一个不同源的窗口发送消息。在你的代码里,iframeWindow.contentWindow 代表 iframe 元素的 window 对象,借助调用该对象的 postMessage 方法,就能向 iframe 内部的页面发送消息。
语法
targetWindow.postMessage(message, targetOrigin, [transfer]);
参数解释
- message:要发送的消息,可以是简单数据类型(如字符串、数字),也能是复杂的对象。在你的代码里,传递的是一个包含 type 和 resource 属性的对象 { type: 'resource', resource: query }。
- targetOrigin:指定目标窗口的源,用于确保消息只会发送到指定源的窗口,增强安全性。它可以是具体的 URL(如 https://example.com),也可以是通配符 *(表示可以发送到任意窗口,但存在安全风险,不建议在生产环境使用)。在你的代码里使用的是 *。
- transfer(可选):是一个可选的 Transferable 对象数组,用于将所有权从当前窗口转移到目标窗口,例如 MessagePort 或 ArrayBuffer 等。
代码示例
<template>
<iframe
:src="url"
frameborder="0"
width="100%"
height="100%"
@load="load"
sandbox="allow-same-origin allow-scripts allow-modals allow-downloads allow-popups allow-forms clipboard-write"
>
</iframe>
</template>
<script setup>
import { ref, computed } from 'vue'
import { getCookie } from "../../utils/cookies";
const userId = getCookie('userId');
const query = JSON.parse(getCookie('resource'))
const url = computed(() => {
let baseUrl = window.config.CHAT_BASE_URL
query.userId = userId
let params = new URLSearchParams(query)
let url = baseUrl + '?' + params.toString()
return url
})
const load = () => {
console.log(userId);
const iframeWindow = document.querySelector('iframe');
if(iframeWindow && iframeWindow.contentWindow) {
// 向 iframe 的 window 对象发送消息
iframeWindow.contentWindow.postMessage({
type: 'resource',
resource: query
}, window.config.CHAT_BASE_URL); // 建议替换为具体的目标源
}
}
</script>
接收消息
在 iframe 内部的页面,需要监听 message 事件来接收消息:
// 在 iframe 页面中
window.addEventListener('message', (event) => {
// 验证消息来源
if (event.origin === 'https://your-main-domain.com') {
const data = event.data;
console.log('接收到的消息:', data);
}
});
通过这种方式,主页面和 iframe 页面就能在跨域或同域的情况下进行安全的通信。