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>" ] }
popup.html
<!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>
popup.js
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可以彻底解决这个问题:
修改后的代码
popup.js
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; });
关键说明
- 替换window.open:使用
chrome.windows.create能直接获取新窗口的标签页信息,不受popup生命周期的影响。 - 精准监听加载状态:通过
chrome.tabs.onUpdated确保新窗口页面完全加载后再发送消息,避免提前发送导致接收失败。 - 原生通信API:
chrome.tabs.sendMessage和chrome.runtime.onMessage是Chrome扩展内部通信的标准方式,兼容性更强,不会因为popup关闭而失效。
内容的提问来源于stack exchange,提问作者Marcolino Scavon
相关产品推荐
相关产品推荐

