Chrome扩展中contentScript.js发送的消息popup.js接收不到如何解决
Chrome扩展contentScript向popup传消息无响应解决方案
原代码失效核心原因
你写的逻辑本质问题是popup页面的生命周期极短:popup只有在用户点击扩展图标处于展开状态时,才会加载执行popup.js、注册监听器;只要用户点击页面其他位置关闭popup,整个popup的上下文就会完全销毁,不存在运行中的监听器。
你在contentScript的window.onload阶段发消息时,99%的概率popup没有打开,Chrome会直接丢弃没有接收方的runtime消息,不会抛出任何报错,就是你看到的现象。
可选解决方案
方案1:popup打开后主动拉取数据(最常用、最稳定)
不需要contentScript主动发消息,改为popup启动时主动向当前页面的contentScript请求数据:
1. popup.js 代码
// popup加载完成后,查询当前激活的标签页,向对应contentScript发请求 chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { chrome.tabs.sendMessage(tabs[0].id, {action: "fetchMarkup"}, (response) => { if (response) { alert("Message Received! 页面源码长度:" + response.markup.length); } }); });
2. contentScript.js 代码
// 监听来自popup的请求,返回需要的数据 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === "fetchMarkup") { sendResponse({markup: document.documentElement.innerHTML}); } });
方案2:contentScript先存数据到storage,popup打开后读取
适合需要页面加载完成就缓存数据、不管popup什么时候打开都能拿到的场景:
1. 先在manifest.json添加storage权限
// Manifest V3示例 "permissions": ["storage"]
2. contentScript.js 代码
window.onload = function() { const markup = document.documentElement.innerHTML; // 存到扩展本地存储 chrome.storage.local.set({pageMarkup: markup}, () => { alert("Content data saved"); }); };
3. popup.js 代码
// popup打开时直接读存储 chrome.storage.local.get("pageMarkup", (result) => { if (result.pageMarkup) { alert("Message Received! 页面源码长度:" + result.pageMarkup.length); } });
必选配置检查
不管用哪种方案,都要确保manifest.json配置正确:
- 已经正确声明contentScript的匹配规则,对应js文件路径正确
- 如果用Manifest V3,不要把popup的监听器写到service worker里,service worker的上下文和popup是隔离的
- 跨域页面注入contentScript需要对应
host_permissions配置(Manifest V3)或者matches配置正确
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

