Chrome扩展onUpdated发消息报错:无法建立连接 接收端不存在
问题根因
报错Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.以及逻辑不生效的原因共4点:
chrome.tabs.onUpdated事件会对页面内所有嵌入的iframe触发,eBay搜索页包含大量跨域iframe,这类iframe不会注入你的content script,向对应tabId发消息必然触发接收端不存在错误- 扩展安装、更新前已经打开的eBay标签页,默认不会自动注入content script,此时发消息无接收端
- 代码存在字段大小写不匹配的逻辑bug:background中发送的消息字段为
searchID(尾字母大写D),content script中解构时写的是searchId(尾字母小写d),即便消息连通也无法正确获取搜索关键词 - 原逻辑中手动用正则split解析URL参数的写法鲁棒性极差,只要eBay调整URL参数顺序就会解析失败,且eBay搜索是单页应用(SPA),站内跳转、翻页不会触发页面完整刷新,原监听逻辑无法捕获这类场景的URL变化
可直接落地的修复方案
1. 更新manifest.json配置
在permissions数组中补充scripting权限,用于手动给未注入脚本的标签页注入content script,修改后权限段如下:
"permissions": ["storage", "tabs", "scripting"],
其余配置保留你之前加的run_at: "document_end"即可,无需改动。
2. 重写background.js逻辑
过滤iframe触发的事件、增加发送失败兜底注入逻辑、兼容扩展安装后的存量标签页、替换URL解析逻辑,代码如下:
// background.js // 扩展安装/更新时,给所有已打开的eBay页面主动注入content script chrome.runtime.onInstalled.addListener(() => { chrome.tabs.query({ url: "https://*.ebay.com/*" }, (tabs) => { tabs.forEach(tab => { chrome.scripting.executeScript({ target: { tabId: tab.id, allFrames: false }, files: ["contentScript.js"] }).catch(() => {}); }); }); }); chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { // 仅处理主框架的页面加载完成事件,跳过所有iframe if ( changeInfo.status !== "complete" || changeInfo.frameId || // 非0值为iframe,直接跳过 !tab.url?.includes("ebay.com/sch") ) return; // 用原生URL对象解析参数,替代不稳定的正则split逻辑 const targetUrl = new URL(tab.url); const searchKeyword = targetUrl.searchParams.get("nkw"); const messagePayload = { type: "NEW", searchID: searchKeyword }; // 发送消息时捕获异常,接收端不存在时主动注入脚本后重发 chrome.tabs.sendMessage(tabId, messagePayload).catch(() => { chrome.scripting.executeScript({ target: { tabId: tabId, allFrames: false }, files: ["contentScript.js"] }).then(() => { chrome.tabs.sendMessage(tabId, messagePayload); }); }); });
3. 修正contentScript.js逻辑
统一字段名、避免重复注入、增加SPA路由变化监听,代码如下:
// contentScript.js // 防止脚本重复注入 if (window.ebayListingRemoverInjected) return; window.ebayListingRemoverInjected = true; let currentSearch = null; // 消息监听,字段名和background保持一致 chrome.runtime.onMessage.addListener((obj) => { const { type, searchID } = obj; if (type === "NEW") { currentSearch = searchID; newSearchLoaded(); } }); // 监听单页应用路由变化,覆盖不刷新页面的站内跳转、翻页场景 let lastPageUrl = location.href; new MutationObserver(() => { const currentUrl = location.href; if (currentUrl !== lastPageUrl && currentUrl.includes("ebay.com/sch")) { lastPageUrl = currentUrl; const urlObj = new URL(currentUrl); currentSearch = urlObj.searchParams.get("nkw"); newSearchLoaded(); } }).observe(document, { subtree: true, childList: true }); // 原有newSearchLoaded业务逻辑保留在下方即可 function newSearchLoaded() { // 自定义业务代码 }
修改完成后重新在扩展管理页面加载扩展,刷新已打开的eBay标签页即可正常运行,不会再抛出连接错误,同时可以覆盖eBay站内不刷新跳转的场景。
内容的提问来源于stack exchange,提问作者Hydrolox
相关产品推荐
相关产品推荐

