跨不同URL标签页长连接传消息报错:接收端不存在
跨标签页长连接消息传递报错排查
问题场景
我想在不同URL的标签页间通过长连接传递消息,设计思路是借助两个content script和background.js中转:
- 在
www.website1.com注入content script (1),代码如下:
const port = chrome.runtime.connect({name: "my_chanel"}); port.postMessage({file: 'some static message'});
- background.js接收消息后,打开
www.website2.org新标签页并转发消息:
chrome.runtime.onConnect.addListener(port => { if (port.name === "my_chanel") { port.onMessage.addListener(msg => { // 等待来自content script (1)的消息 if (msg?.file) { chrome.tabs.create({url:'www.website2.org'}, newTab => { // 打开新标签并转发消息 const port = chrome.tabs.connect(newTab.id, {name: "my_chanel"}); port.postMessage(msg); }); } else { console.error('Service worker got empty message from 1st content script'); } }); } });
- 在
www.website2.org注入content script (2)等待消息:
const port = chrome.runtime.connect({name: "my_chanel"}); port.onMessage.addListener(msg => { console.log(msg.file); });
报错情况
除content script (2)外其他部分正常,运行时抛出如下错误:
Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
已排除一次性请求场景、异步调用问题,且禁用了其他扩展,求问问题原因?
问题原因及解决方法
核心问题是新标签页加载完成前,background就尝试建立长连接并发送消息,此时content script (2)还未注入运行,导致接收端不存在。
具体修复步骤:
等待新标签页完全加载后再建立连接
修改background.js,在chrome.tabs.create回调中监听标签页的onUpdated事件,确认标签页状态变为complete后,再执行连接和消息转发:chrome.runtime.onConnect.addListener(port => { if (port.name === "my_chanel") { port.onMessage.addListener(msg => { if (msg?.file) { chrome.tabs.create({url:'www.website2.org'}, newTab => { // 监听标签页加载状态,完成后执行操作 const loadListener = (tabId, changeInfo) => { if (tabId === newTab.id && changeInfo.status === 'complete') { chrome.tabs.onUpdated.removeListener(loadListener); // 移除监听器避免重复触发 const port = chrome.tabs.connect(newTab.id, {name: "my_chanel"}); port.postMessage(msg); } }; chrome.tabs.onUpdated.addListener(loadListener); }); } else { console.error('Service worker got empty message from 1st content script'); } }); } });确保content script (2)的注入时机正确
在manifest.json中配置content script时,需明确匹配www.website2.org,并设置合适的注入时机(默认document_idle即可保证页面基本加载完成后注入):"content_scripts": [ { "matches": ["*://www.website2.org/*"], "js": ["content-script2.js"], "run_at": "document_idle" } ]修正命名拼写(非核心但建议统一)
代码中my_chanel存在拼写错误,正确应为my_channel,统一命名可避免后续维护混淆。
内容的提问来源于stack exchange,提问作者1_bug
相关产品推荐
相关产品推荐

