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

关于chrome.tabs.sendMessage及Promise使用的技术问题咨询

问题根因
  • 内容脚本的chrome.runtime.onMessage监听函数处理异步逻辑时,没有显式返回true:Chrome扩展的消息通信机制中,如果监听函数内需要异步执行后再调用sendResponse,必须返回true告知浏览器保留sendResponse通道,否则浏览器会判定监听函数无返回值,直接触发sendMessage的回调,回调参数为undefined。
  • 内容脚本未成功注入当前页面:如果当前活跃标签页没有加载匹配的内容脚本、或内容脚本未注册消息监听逻辑,Chrome会直接触发sendMessage回调,无返回值。
  • 回调与Promise写法混用:Manifest V3版本的chrome.tabs.sendMessage原生支持Promise返回,如果同时传入回调函数又使用await,会导致逻辑执行顺序混乱。
修复方案

1. 修正内容脚本的消息监听逻辑

在异步处理逻辑结束后调用sendResponse,末尾显式返回true:

// 内容脚本代码
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.action === "getDOM") {
    // 你的异步处理逻辑,比如DOM遍历、接口请求等
    const result = {
      incident: [/* 处理后的数据 */]
    }
    // 异步场景下(存在await、setTimeout等异步操作)必须调用sendResponse返回结果
    sendResponse(result)
    // 关键:返回true告知浏览器等待异步响应,不要销毁通信通道
    return true
  }
})

2. 修正Popup代码逻辑

移除回调写法,直接使用await调用chrome.tabs.sendMessage,用try/catch捕获异常:

document.addEventListener('DOMContentLoaded', async function() {
    console.log('got tabs id');
    const tab = await getCurrentTab();
    console.log('Active tab ' + tab.id);
    console.log('Sending Message to Content');
    try {
      // 直接await sendMessage的返回值,无需传入回调
      const ret = await chrome.tabs.sendMessage(tab.id, {action: "getDOM"});
      console.log('Receiving Message from Content');
      if (!ret?.incident?.length) return;
      globalThis.response = ret;
      processResponse(response);
    } catch(err) {
      // 可打印chrome.runtime.lastError查看具体错误原因
      console.log('doing nothing, bad return data', err)
      window.close();
      return;
    }
    return;
}); 

3. 排查验证路径

  • 在内容脚本的监听函数第一行打印日志,确认消息已成功送达内容脚本
  • 检查Manifest配置中内容脚本的匹配规则,确认当前活跃页面符合匹配规则,内容脚本已成功注入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:57:04