You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展跨窗口postMessage在Windows正常,macOS下无响应求助

问题

开发的Chrome扩展在Windows系统上正常工作,但在macOS的Chrome浏览器中,点击popup按钮打开的新窗口始终显示“Waiting for message...”,无法接收popup发送的postMessage消息。

复现代码

manifest.json

{
  "manifest_version": 3,
  "name": "Simple PostMessage Extension",
  "version": "1.0",
  "description": "Test postMessage between windows",
  "action": {
    "default_popup": "popup.html",
    "default_icon": "icon.png"
  },
  "permissions": [
    "storage",
    "activeTab",
    "tabs",
    "scripting"
  ],
  "host_permissions": [
    "<all_urls>"
  ]
}
<!DOCTYPE html>
<html>
<head>
  <title>Popup</title>
  <script src="popup.js" defer></script>
</head>
<body>
  <h1>Simple PostMessage Test</h1>
  <button id="openWindowButton">Open New Window</button>
</body>
</html>
document.getElementById('openWindowButton').addEventListener('click', () => {
    var newWindow = window.open('newWindow.html');   
    newWindow.addEventListener('load', () => {
        newWindow.postMessage({ test: 'Hello from the popup!' }, '*');
    });
});

newWindow.html

<!DOCTYPE html>
<html>
<head>
  <title>New Window</title>
  <script src="newWindow.js" defer></script>
</head>
<body>
  <h1>New Window</h1>
  <p id="messageDisplay">Waiting for message...</p>
</body>
</html>

newWindow.js

window.addEventListener('message', (event) => {
    document.getElementById('messageDisplay').textContent = 'Message received: ' + event.data.test;
});

预期与实际行为

  • 预期:点击按钮后新窗口显示“Message received: Hello from the popup!”
  • 实际:Windows系统运行正常;macOS系统新窗口停留在“Waiting for message...”状态,控制台无报错

解决方案

macOS上Chrome的popup窗口在打开新窗口后会快速失去焦点并自动销毁,导致load回调执行时popup的上下文已不存在,postMessage无法成功发送。改用Chrome扩展原生的消息通信API可以彻底解决这个问题:

修改后的代码

document.getElementById('openWindowButton').addEventListener('click', () => {
    // 使用Chrome扩展API创建新窗口,确保获取到标签页ID
    chrome.windows.create({
        url: chrome.runtime.getURL('newWindow.html'),
        type: 'popup'
    }, (newWindow) => {
        const targetTabId = newWindow.tabs[0].id;
        // 监听目标标签页的加载完成状态
        const loadListener = (tabId, changeInfo) => {
            if (tabId === targetTabId && changeInfo.status === 'complete') {
                // 通过扩展原生API发送消息
                chrome.tabs.sendMessage(targetTabId, { test: 'Hello from the popup!' });
                // 移除监听避免重复触发
                chrome.tabs.onUpdated.removeListener(loadListener);
            }
        };
        chrome.tabs.onUpdated.addListener(loadListener);
    });
});

newWindow.js

// 监听扩展内部消息
chrome.runtime.onMessage.addListener((message) => {
    document.getElementById('messageDisplay').textContent = 'Message received: ' + message.test;
});

关键说明

  1. 替换window.open:使用chrome.windows.create能直接获取新窗口的标签页信息,不受popup生命周期的影响。
  2. 精准监听加载状态:通过chrome.tabs.onUpdated确保新窗口页面完全加载后再发送消息,避免提前发送导致接收失败。
  3. 原生通信API:chrome.tabs.sendMessage和chrome.runtime.onMessage是Chrome扩展内部通信的标准方式,兼容性更强,不会因为popup关闭而失效。

内容的提问来源于stack exchange,提问作者Marcolino Scavon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:03:14