使用 postMessage API 来实现跨窗口(跨域)的消息传递。postMessage 允许你安全地发送消息到其他窗口,包括嵌套的 iframe,而不需要担心同源策略的问题。
发送消息(父应用)
1. 父应用:发送消息给子应用
父应用可以通过 postMessage 将消息发送给子应用。需要注意的是,发送消息时,需要指定目标窗口和目标窗口的来源(即目标 iframe 的 origin),以确保安全性。
iframe.contentWindow.postMessage(message, targetOrigin)
使用 postMessage 向子应用发送消息。message 是要发送的数据,可以是任何 JavaScript 对象。targetOrigin 是目标窗口的源(例如:http://child-app.com),它确保消息只发送到具有这个源的窗口。
2、接收消息(子应用)
子应用通过监听 message
事件来接收父应用发送的消息。收到消息后,子应用可以根据消息中的 type
字段来执行不同的操作。
示例:父应用与子应用通信
1. 父应用:发送消息给子应用
父应用通过 postMessage 向 iframe 中的子应用发送一个包含 type 的消息。我们还可以通过 targetOrigin 来确保消息只发送到指定的子应用。
<!-- 父应用 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Parent App</title>
</head>
<body>
<h1>Parent Application</h1>
<!-- iframe 中嵌套子应用 -->
<iframe id="childIframe" src="http://child-app.com" width="600" height="400"></iframe>
<button onclick="sendMessageToChild()">发送消息到子应用</button>
<script>
// 发送消息到子应用
function sendMessageToChild() {
const iframe = document.getElementById('childIframe');
const message = {
type: 'CLEAR_INPUT', // 消息类型
data: { message: '请清空输入框' }
};
// 使用 postMessage 发送消息到子应用
iframe.contentWindow.postMessage(message, 'http://child-app.com'); // 子应用的 origin
}
</script>
</body>
</html>
2. 子应用:接收父应用发送的消息
子应用会监听 message
事件,接收到消息后可以处理它。通常可以根据 message.type
来决定如何处理消息。
<!-- 子应用 (iframe 内容) -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Child App</title>
</head>
<body>
<h1>Child Application</h1>
<input type="text" id="inputField" placeholder="请输入内容...">
<script>
// 监听父应用发送的消息
window.addEventListener('message', function(event) {
// 验证消息的来源
if (event.origin !== 'http://parent-app.com') {
return; // 如果消息来源不正确,则忽略
}
const message = event.data;
console.log('Received message from parent:', message);
// 根据消息的 type 执行不同操作
if (message.type === 'CLEAR_INPUT') {
document.getElementById('inputField').value = ''; // 清空输入框
}
});
</script>
</body>
</html>
如何在vue本地项目进行iframe测试通讯
1、新建一个iframe.vue页面,为父页面
// 父应用
<template>
<div class="act-form">
<iframe :src="src" id="childIframe" width="600" height="400"></iframe>
<el-button @click="sendMessage">向iframe发送信息</el-button>
</div>
</template>
<script>
export default {
data () {
return {
src: '',
}
},
created() {
// 当前我本地运行的端口为 localhost:8080 需要根据实际情况调动
this.src = 'http:localhost:8080/home?id=18'
},
methods: {
sendMessage () {
const iframe = document.getElementById('childIframe');
const message = {
type: 'CLEAR_INPUT', // 消息类型
data: { message: '请清空输入框' }
};
// 使用 postMessage 发送消息到子应用
iframe.contentWindow.postMessage(message, this.src); // 子应用的origin
},
},
}
}
</script>
2、子应用
<!-- 子应用 (iframe 内容) -->
<template>
<div>
// 内容区域
</div>
</template>
<script>
export default {
data () {
return {
},
created() {
// 在外部vue的window上添加postMessage的监听,并且绑定处理函数handleMessage
window.addEventListener('message', this.handleMessage)
},
methods: {
handleMessage (event) {
// 根据上面制定的结构来解析iframe内部发回来的数据
// 验证消息的来源
if (event.origin !== 'http://parent-app.com') {
return; // 如果消息来源不正确,则忽略
}
const message = event.data;
console.log('Received message from parent:', message);
// 根据消息的 type 执行不同操作
if (message.type === 'CLEAR_INPUT') {
// 在这里执行你需要的逻辑
}
});
}
}
beforeDestroy(){ // 页面关闭移除监听
window.removeEventListener("message", this.handleMessage);
}
</script>