You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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});
  }
})

原有逻辑可正常运行,无需大改:

chrome.runtime.sendMessage({from:'popup',msg:"send info"}, (response) => {
  console.log(response)
  // 在这里写你的数据渲染逻辑
});

补充说明

如果你使用的是 Manifest V3 版本扩展,后台运行环境为 Service Worker,会在闲置时被浏览器自动回收,全局变量会随之清空。上述修复代码已经兼容这个场景:哪怕缓存被清空,popup发起请求时会主动向当前页面的content脚本拉取最新的预处理数据,不会出现空值问题,全程不需要调用storage相关API。

内容的提问来源于stack exchange,提问作者Volatil3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:54:28