Chrome扩展中popup.js无法向content.js发送消息的问题
解决Chrome扩展Popup与Content脚本消息通信的两个错误
错误1:Could not establish connection. Receiving end does not exist.
该错误核心是发送消息时,目标标签页内无有效消息接收者,或消息通道未正确维持,可从以下两点修复:
1. 修正Content脚本的消息监听器逻辑
在Manifest V3中,若使用异步函数处理onMessage回调,必须**显式返回true**告知Chrome保持消息通道开放,直到sendResponse执行完成,否则通道会提前关闭导致通信失败。修改后的content.js:
console.log("content script running"); chrome.runtime.onMessage.addListener(async 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"}); } // 返回true维持异步响应的通道 return true; });
2. 确保Content脚本已加载到目标页面
- 确认当前激活标签页的URL完全匹配
manifest.json中content_scripts的matches规则:https://discord.com/channels/*,需是具体频道页面而非Discord首页。 - 若页面是扩展安装/更新后打开的,需刷新页面触发Content脚本加载。
错误2:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'id')
该错误因chrome.tabs.query()未获取到有效标签页,导致tab变量为undefined,可通过以下方式修复:
优化Popup.js的标签页获取逻辑
调整查询参数并增加合法性校验,确保仅向符合条件的标签页发送消息:
const sendMessageBtn = document.querySelector("button"); sendMessageBtn.addEventListener("click", async () => { console.log("clicked"); // 使用currentWindow确保获取Popup所在窗口的激活标签,比lastFocusedWindow更准确 const tabs = await chrome.tabs.query({ active: true, currentWindow: true, }); // 校验是否获取到有效标签页 if (!tabs || tabs.length === 0) { console.error("无法获取激活标签页"); return; } const tab = tabs[0]; // 校验标签页URL是否匹配Content脚本范围 if (!tab.url?.startsWith("https://discord.com/channels/")) { console.error("当前标签页非目标Discord频道页面"); return; } try { const response = await chrome.tabs.sendMessage(tab.id, { greeting: "hello" }); console.log(response); } catch (err) { console.error("消息发送失败:", err); } });
额外验证步骤
- 打开
chrome://extensions/,开启开发者模式,点击扩展的「检查视图」→「检查弹出窗口」查看Popup控制台日志。 - 在Discord频道页面按F12打开控制台,确认
content script running已打印,说明Content脚本加载正常。 - 发送消息前,确保当前激活标签页为符合URL规则的Discord频道页面。
内容的提问来源于stack exchange,提问作者AKHIL PANWAR
相关产品推荐
相关产品推荐

