Chrome扩展:后台脚本向内容脚本发消息报错求助
解决Chrome扩展后台脚本向内容脚本发送消息失败的问题
问题原因
报错Could not establish connection. Receiving end does not exist.的核心原因是:当后台脚本调用chrome.tabs.sendMessage时,目标标签页中并未注入对应的内容脚本。你提到内容脚本采用编程方式注入但未在manifest中声明,但现有代码完全没有触发注入的逻辑,导致接收端不存在。
解决方案
步骤1:添加必要权限
修改manifest.json,新增scripting权限(Manifest V3中编程注入内容脚本需要该权限):
{ "name": "chrome extension", "version": "1.0.0", "description": "Extension", "icons": { "16": "images/16.png", "32": "images/32.png", "48": "images/48.png", "128": "images/96.png" }, "manifest_version": 3, "author": "", "background": { "service_worker": "background.js", "type": "module" }, "permissions":[ "bookmarks", "storage", "tabs", "activeTab", "scripting" // 新增该权限 ], "action":{ "default_popup": "index.html", "default_title": "Extension" }, "commands": { "switch-to-folder-1": { "suggested_key": "Ctrl+Shift+1", "description": "Switch folder 1" } } }
步骤2:修改后台脚本,先注入内容脚本再发消息
方式1:直接在后台脚本中定义内容脚本逻辑
chrome.commands.onCommand.addListener(async (command) => { const [tab] = await chrome.tabs.query({active: true, currentWindow: true}); try { // 先注入内容脚本逻辑 await chrome.scripting.executeScript({ target: {tabId: tab.id}, func: () => { chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { console.log( sender.tab ? 'from a content script:' + sender.tab.url : 'from the extension' ); if (request.greeting === 'hello') sendResponse({ farewell: 'goodbye' }); }); } }); // 注入完成后发送消息 const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"}); console.log(response); } catch (err) { console.error('操作失败:', err); } });
方式2:引用外部内容脚本文件(更规范)
- 将内容脚本逻辑单独保存为
content.js文件:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { console.log( sender.tab ? 'from a content script:' + sender.tab.url : 'from the extension' ); if (request.greeting === 'hello') sendResponse({ farewell: 'goodbye' }); });
- 修改后台脚本,注入外部文件后发送消息:
chrome.commands.onCommand.addListener(async (command) => { const [tab] = await chrome.tabs.query({active: true, currentWindow: true}); try { // 注入外部内容脚本文件 await chrome.scripting.executeScript({ target: {tabId: tab.id}, files: ['content.js'] // 确保文件路径正确 }); const response = await chrome.tabs.sendMessage(tab.id, {greeting: "hello"}); console.log(response); } catch (err) { console.error('操作失败:', err); } });
可选方案:自动注入内容脚本
如果需要在特定网站自动注入内容脚本,可在manifest.json中声明content_scripts字段,这样扩展加载时会自动注入到匹配的网站,无需手动触发:
{ // ... 其他原有配置 "content_scripts": [ { "matches": ["<all_urls>"], // 可替换为特定域名,如"https://*.example.com/*" "js": ["content.js"] } ], // ... 其他原有配置 }
这种方式下,后台脚本可直接调用chrome.tabs.sendMessage,无需手动注入。
内容的提问来源于stack exchange,提问作者AspiringMainframeDev
相关产品推荐
相关产品推荐

