Chrome扩展V3迁移:网页向contentScript发消息失败求助
问题原因分析
你遇到的Could not establish connection. Receiving end does not exist.错误核心原因是:网页通过chrome.runtime.sendMessage发送的外部消息,无法直接被content script接收。在Manifest V3中,externally_connectable配置允许网页与扩展通信,但这类消息的接收端只能是扩展的background service worker,content script无法直接监听来自外部网页的消息。
此外,你的content script里的chrome.runtime.onMessage只能监听来自扩展内部(比如background、popup)的消息,对网页发送的外部消息无响应,所以网页端会提示接收端不存在。
解决方案
需要通过background service worker作为中间层,转发网页的消息到目标标签页的content script,具体步骤如下:
1. 更新background.js,添加网页消息监听与转发逻辑
创建或修改background.js,添加以下代码:
// 监听来自网页的外部消息 chrome.runtime.onMessageExternal.addListener((request, sender, sendResponse) => { // 验证发送来源(可选,但更安全) if (!sender.url.match(/https?:\/\/.*\.devSite\.com\/.*/)) { return; } // 获取当前活跃标签页,转发消息到该标签页的content script chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { if (tabs.length === 0) return; chrome.tabs.sendMessage(tabs[0].id, request, (response) => { // 可选:把content script的响应回传给网页 sendResponse(response); }); }); // 必须返回true,否则sendResponse会在函数结束后失效(异步场景) return true; });
2. 确保content script能正确处理消息
你的content script代码无需修改,但可以加一段初始化日志验证注入状态:
console.log('Content script loaded successfully'); chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if(request.message === 'print') { console.log('lets print'); // 可选:给background返回响应 sendResponse({status: 'print_received'}); } });
3. 检查并修正Manifest配置
- 确认
externally_connectable中的matches和ids配置正确:matches必须包含你的网页域名(比如*://*.devSite.com/*)ids里的扩展ID要和你实际的扩展ID一致
- 移除
web_accessible_resources中不必要的contentScript.js和background.js——这两个文件不需要暴露给网页,反而有安全风险
修正后的Manifest相关配置片段:
"web_accessible_resources": [ { "resources": ["popup/popup.js", "popup/popup.html"], "matches": ["*://*/*"] } ], "externally_connectable": { "ids": ["lahnkkonafcepfnlcdjambbbeaocjdbk"], "matches": ["*://*.devSite.com/*"] }
4. 验证网页端代码
确保test.php中的CHROME_EXTENSION_ID替换为你扩展的实际ID,并且网页在externally_connectable配置的matches域名下运行:
<script> const CHROME_EXTENSION_ID = 'lahnkkonafcepfnlcdjambbbeaocjdbk'; chrome.runtime.sendMessage(CHROME_EXTENSION_ID, { message: "print" }, (response) => { if (chrome.runtime.lastError) { console.error('Error:', chrome.runtime.lastError); return; } console.log("Response from extension:", response); } ); </script>
额外排查点
- 确认扩展已重新加载,并且在测试网页的标签页中,content script已正确注入(可以在Chrome开发者工具的
Sources面板中查看Content scripts标签) - 如果你的网页是本地开发环境(比如
http://localhost),需要在host_permissions和externally_connectable.matches中添加对应的域名规则
内容的提问来源于stack exchange,提问作者cempro
相关产品推荐
相关产品推荐

