postMessage 是一种用于跨源通信的 API,通常用于在不同的窗口、iframe 或者 Web Worker 之间传递消息。它也可以用于多个标签页之间的通信,但需要一些额外的手段来实现。
基本原理
postMessage 允许一个窗口向另一个窗口发送消息,甚至这些窗口来自不同的源。接收消息的窗口可以通过 message 事件监听器来处理这些消息。
多个标签页之间的通信
为了在多个标签页之间实现通信,可以利用 postMessage 和 BroadcastChannel API 的组合。BroadcastChannel API 允许页面之间广播消息,而 postMessage 可以在不同的窗口之间传递消息。
示例代码
以下是一个完整的示例,展示如何使用 postMessage 和 BroadcastChannel 在多个标签页之间进行通信。
主页面代码(index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>postMessage Communication</title>
</head>
<body>
<button onclick="openNewTab()">Open New Tab</button>
<button onclick="sendMessage()">Send Message</button>
<script>
let newTab;
const channel = new BroadcastChannel('my_channel');
function openNewTab() {
newTab = window.open('about:blank', '_blank');
newTab.document.write(`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>New Tab</title>
</head>
<body>
<h1>New Tab</h1>
<script>
const channel = new BroadcastChannel('my_channel');
window.addEventListener('message', function(event) {
console.log('Received message from main tab:', event.data);
channel.postMessage(event.data);
});
channel.addEventListener('message', function(event) {
console.log('Received broadcast message:', event.data);
});
<\/script>
</body>
</html>
`);
}
function sendMessage() {
const message = 'Hello from the main tab!';
if (newTab) {
newTab.postMessage(message, '*');
}
channel.postMessage(message);
}
channel.addEventListener('message', function(event) {
console.log('Received broadcast message:', event.data);
});
</script>
</body>
</html>
-
打开新标签页:
openNewTab函数使用window.open打开一个新的标签页,并将一些 HTML 和 JavaScript 写入新标签页。- 新标签页中包含一个
BroadcastChannel实例,用于接收来自其他标签页的广播消息。 - 新标签页还监听
message事件,以接收来自主标签页的消息,并通过BroadcastChannel将消息广播出去。
-
发送消息:
sendMessage函数向新标签页发送消息,并通过BroadcastChannel将消息广播出去。- 如果新标签页存在,使用
postMessage将消息发送到新标签页。 - 使用
BroadcastChannel将消息广播到所有监听该频道的标签页。
-
接收消息:
- 主标签页和新标签页都监听
BroadcastChannel的message事件,以接收广播消息。 - 新标签页还监听
message事件,以接收来自主标签页的消息。
- 主标签页和新标签页都监听
通过结合使用 postMessage 和 BroadcastChannel,可以在多个标签页之间实现高效的通信。这种方法不仅适用于同源的标签页,也适用于跨源的标签页。postMessage 用于在不同窗口之间传递消息,而 BroadcastChannel 则用于在多个标签页之间广播消息。