Chrome扩展中popup.js、content.js与background.js通信失败求助
Chrome扩展三端通信故障排查
我编写了Chrome扩展的popup.js、background.js和content.js通信代码,但点击按钮后控制台仅能打印'click check',三端似乎未正常通信。预期的消息流转流程是:popup.js(按钮点击)→background.js→content.js→background.js→popup.js。以下是我的代码,请问问题出在哪里?
manifest.json
{ "manifest_version": 3, "name": "Chrome Extension", "version": "0.1.0", "description": "project", "icons": { "32": "icons/icon_32.png" }, "background": { "service_worker": "background.js", "icon": "icon-34.png" }, "action": { "default_title": "Chrome Extension", "default_popup": "popup.html" }, "host_permissions": [ "https://*/*" ], "permissions": [ "storage", "activeTab", "tabs", "scripting" ] }
popup.js
function start(){ let link = document.getElementById('request-btn'); if(link){ link.addEventListener('click', function() { console.log('click check'); // 这段代码能正常打印 chrome.runtime.sendMessage({ type: "popup_send" }) }); } } chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.type === "html") { console.log("HTML received in popup.js: ", request.data); console.log('popup check'); } }); window.onload = start;
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.type === "content_send") { chrome.runtime.sendMessage({ type: "html", data: "background_send" }) } else if(request.type === 'popup_send'){ chrome.runtime.sendMessage({ type: "content_request" }) } });
content.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){ if(request.type === "content_request"){ chrome.runtime.sendMessage({ type: "content_send" }) } })
问题根源及修复方案
1. Content脚本未被注入页面
当前manifest.json中没有声明content_scripts字段,导致content.js根本没有被加载到目标网页中,自然收不到任何消息。
修复:在manifest.json中添加content_scripts配置
在manifest的根节点下添加:
"content_scripts": [ { "matches": ["https://*/*"], "js": ["content.js"] } ]
这个配置会在所有HTTPS页面自动注入content.js,和你现有的host_permissions匹配。
2. Background向Content发消息的方式错误
在Manifest V3中,chrome.runtime.sendMessage是用于扩展内部脚本(比如popup和background之间)通信的API,要给网页中的content脚本发消息,必须使用chrome.tabs.sendMessage,并指定目标标签页的ID。
修复:修改background.js中popup_send分支的代码
把原来直接发送runtime消息的逻辑改成获取当前活跃标签页,再发送tabs消息:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.type === "content_send") { chrome.runtime.sendMessage({ type: "html", data: "background_send" }) } else if(request.type === 'popup_send'){ // 获取当前活跃标签页,向其注入的content脚本发消息 chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { if(tabs.length > 0){ chrome.tabs.sendMessage(tabs[0].id, { type: "content_request" }); } }); } });
3. 注意控制台的查看位置
不同脚本的控制台输出位置不同,不要找错:
- popup的控制台:右键扩展图标→检查
- background的控制台:扩展管理页面→点击"服务工作者"后的"检查"按钮
- content脚本的控制台:当前网页的开发者工具控制台
内容的提问来源于stack exchange,提问作者hyehye
相关产品推荐
相关产品推荐

