Chrome扩展contextMenus的sendResponse在部分页面失效求助
问题分析与解决方案
报错Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.的核心原因是:目标标签页中未注入对应的content script(比如页面在扩展安装/启用前打开,或service worker发送消息时content script未完成初始化),导致background无法建立消息连接。
以下是修复后的完整代码及说明:
1. 更新manifest.json
添加scripting权限,用于动态注入content script:
{ "manifest_version": 3, "name": "Words Repeater", "description": "Repeat words what you want to memorize", "version": "1.0.0", "permissions": ["contextMenus", "activeTab", "tabs", "scripting"], "action": { "default_popup": "popup.html" }, "background": { "service_worker": "./js/background.js" }, "content_scripts": [ { "matches": ["http://*/*", "https://*/*"], "js": ["./js/content.js"] } ] }
2. 修改background.js
修正参数错误,优化右键菜单触发条件,并添加动态注入content script的逻辑:
//background.js chrome.runtime.onInstalled.addListener((details) => { chrome.contextMenus.create({ id: 'addWords', title: "Send \"%s\" to background", contexts: ['selection'] // 仅在选中文本时显示菜单,避免无效触发 }) }); function getSelection(info, tab) { if (info.menuItemId === "addWords") { const sendRequest = () => { chrome.tabs.sendMessage(tab.id, {action: "getSelection"}, (response) => { if (!chrome.runtime.lastError) { console.log(response); } }); }; // 先尝试发送消息,失败则动态注入content script后重试 chrome.tabs.sendMessage(tab.id, {action: "getSelection"}, (response) => { if (chrome.runtime.lastError) { chrome.scripting.executeScript({ target: {tabId: tab.id}, files: ["./js/content.js"] }, () => { if (!chrome.runtime.lastError) { sendRequest(); } }); } else { console.log(response); } }); } } chrome.contextMenus.onClicked.addListener(getSelection);
3. content.js(保持原有逻辑,可选优化句子提取)
原代码可正常使用,若要优化句子提取(避免将缩写如Mr.误判为句末),可调整分割逻辑,这里保留原代码:
//content.js chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if(request.action === "getSelection"){ let selection = window.getSelection(); if(selection.toString() !== ""){ let arr = selection.anchorNode.data.split("."); let word = selection.toString(); let sentence = arr.find(str => str.includes(word)) alert(word); sendResponse({word: word, sentence: sentence}); } } })
修复说明
- 动态注入content script:当自动注入失效时,通过
chrome.scripting.executeScript手动注入,确保接收端存在。 - 优化菜单触发条件:将
contexts设为selection,仅在用户选中文本时显示右键菜单,减少无效操作。 - 错误处理:捕获消息发送和脚本注入的错误,避免控制台报错影响扩展运行。
内容的提问来源于stack exchange,提问作者Ma Twickenham
相关产品推荐
相关产品推荐

