前端postMessage的应用

350 阅读2分钟

postMessage 是一种用于跨源通信的 API,通常用于在不同的窗口、iframe 或者 Web Worker 之间传递消息。它也可以用于多个标签页之间的通信,但需要一些额外的手段来实现。

基本原理

postMessage 允许一个窗口向另一个窗口发送消息,甚至这些窗口来自不同的源。接收消息的窗口可以通过 message 事件监听器来处理这些消息。

多个标签页之间的通信

为了在多个标签页之间实现通信,可以利用 postMessageBroadcastChannel API 的组合。BroadcastChannel API 允许页面之间广播消息,而 postMessage 可以在不同的窗口之间传递消息。

示例代码

以下是一个完整的示例,展示如何使用 postMessageBroadcastChannel 在多个标签页之间进行通信。

主页面代码(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>
  1. 打开新标签页

    • openNewTab 函数使用 window.open 打开一个新的标签页,并将一些 HTML 和 JavaScript 写入新标签页。
    • 新标签页中包含一个 BroadcastChannel 实例,用于接收来自其他标签页的广播消息。
    • 新标签页还监听 message 事件,以接收来自主标签页的消息,并通过 BroadcastChannel 将消息广播出去。
  2. 发送消息

    • sendMessage 函数向新标签页发送消息,并通过 BroadcastChannel 将消息广播出去。
    • 如果新标签页存在,使用 postMessage 将消息发送到新标签页。
    • 使用 BroadcastChannel 将消息广播到所有监听该频道的标签页。
  3. 接收消息

    • 主标签页和新标签页都监听 BroadcastChannelmessage 事件,以接收广播消息。
    • 新标签页还监听 message 事件,以接收来自主标签页的消息。

通过结合使用 postMessageBroadcastChannel,可以在多个标签页之间实现高效的通信。这种方法不仅适用于同源的标签页,也适用于跨源的标签页。postMessage 用于在不同窗口之间传递消息,而 BroadcastChannel 则用于在多个标签页之间广播消息。