使用 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的監聽,并且綁定處理函數handleMessagewindow.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>