Chrome扩展:如何从content script发送多条sendMessage传值
问题解答
基础能力说明
content script 完全支持发送多条 sendMessage 消息,Chrome 扩展运行时的消息通信接口没有单上下文发送条数限制,只要消息格式合法、接收端监听器正常注册,多消息串行/并行发送都可以正常工作。
现有代码空值原因
你的代码拿不到数据的核心问题是变量作用域错误:你把用来存储预处理结果的 msg_for_popup 声明在了 chrome.runtime.onMessage 的监听回调函数内部,每次后台收到任意消息触发回调时,这个变量都会被重新声明并赋值为空字符串。哪怕 content 脚本上报预处理数据时给它赋过值,等 popup 发请求触发新的回调执行时,变量会被重置为空,自然拿不到之前存的内容。
修复后代码
background.js
把缓存变量移到监听器外部作为全局变量存储,同时补充popup请求时无缓存的兜底拉取逻辑:
// 预处理数据缓存变量移至监听器外,在后台脚本生命周期内持久保存 let msg_for_popup = ''; chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { console.log('Message got by Background') console.log(request) if(request.from === 'content') { getInfo(request.msg).then(sendResponse); return true; } else if(request.from === 'popup') { // 已有缓存直接返回 if (msg_for_popup) { sendResponse('PREPARED DATA = '+msg_for_popup) } else { // 无缓存时主动向当前激活标签页的content脚本拉取预处理结果 chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { const activeTabId = tabs[0]?.id; if (!activeTabId) { sendResponse('PREPARED DATA = '); return; } chrome.tabs.sendMessage(activeTabId, {type: 'fetchPreparedData'}, (res) => { msg_for_popup = res?.preparedData || ''; sendResponse('PREPARED DATA = '+msg_for_popup) }) }) } return true; } else if(request.from === 'prepared') { // 接收content主动上报的预处理结果,更新缓存 msg_for_popup = request.msg console.log('Prepared in BG') console.log(msg_for_popup) sendResponse({code: 0}); } });
content.js
新增后台主动拉取数据的监听逻辑,兼容后台脚本被回收、缓存丢失的场景:
// 原有主动处理+上报逻辑 chrome.runtime.sendMessage({from:'content',msg:document.location.href}, res => { console.log(res); if (res.html) { // 替换为你实际的预处理逻辑结果 const preparedResult = 'Prepared'; chrome.runtime.sendMessage({from:'prepared',msg: preparedResult}); } }); // 监听后台的拉取请求,直接返回已处理好的数据 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === 'fetchPreparedData') { // 替换为你实际存储预处理结果的变量 const preparedResult = 'Prepared'; sendResponse({preparedData: preparedResult}); } })
popup.js
原有逻辑可正常运行,无需大改:
chrome.runtime.sendMessage({from:'popup',msg:"send info"}, (response) => { console.log(response) // 在这里写你的数据渲染逻辑 });
补充说明
如果你使用的是 Manifest V3 版本扩展,后台运行环境为 Service Worker,会在闲置时被浏览器自动回收,全局变量会随之清空。上述修复代码已经兼容这个场景:哪怕缓存被清空,popup发起请求时会主动向当前页面的content脚本拉取最新的预处理数据,不会出现空值问题,全程不需要调用storage相关API。
内容的提问来源于stack exchange,提问作者Volatil3
相关产品推荐
相关产品推荐

