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

Chrome扩展MV3中runtime.sendMessage异步响应返回失败问题求助

Chrome Manifest V3 异步消息返回失败问题解决

问题根因

你代码的核心问题是 chrome.runtime.onMessage 的监听器被声明为了 async 函数:
async函数的返回值默认是Promise对象,你代码中写的 return true 会被自动包装为 Promise.resolve(true),Chrome的消息监听逻辑判断不到原生布尔值true,就会认为你不需要异步返回响应,同步代码执行完毕后直接关闭消息端口,等你await异步逻辑结束再调用sendResponse时,端口已经被销毁,sendResponse也被垃圾回收,自然无法返回结果给content script。
你看到的「The message port closed before a response was received」报错就是这个原因导致的。

修复方案

方案1:使用.then链式调用处理异步逻辑

不要将监听器本身声明为async,直接用Promise的then方法处理异步结果,同步返回true即可:

// background.js 修改后代码
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.message == "Please Respond") {
      myTestPromise().then(testMessage => {
        console.log(testMessage)
        sendResponse({response:testMessage})
      })
  }
  return true;
});

方案2:将异步逻辑包装在立即执行函数(IIFE)中

如果习惯用async/await写法,可以把异步逻辑包在独立的async立即执行函数里,监听器本身保持为普通同步函数,正常返回true:

// background.js 修改后代码
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.message == "Please Respond") {
    // 异步逻辑放在独立的IIFE中,不影响监听器本身的返回值
    (async () => {
      const testMessage = await myTestPromise();
      console.log(testMessage)
      sendResponse({response:testMessage})
    })()
  }
  return true;
});

拓展优化:content script 支持Promise写法

Manifest V3的chrome.runtime.sendMessage原生支持Promise调用,不需要写回调函数,写法更简洁:

// mORS.js 可选优化写法
(async () => {
  try {
    const response = await chrome.runtime.sendMessage({ message: "Please Respond" });
    console.log(`Response:`, response)
    if (response.response == "Success") {
      console.log("Success!")
    }
  } catch (error) {
    console.log(error)
  }
})()

术语补充说明

你之前疑惑的「垃圾回收」在这里特指:Chrome如果判断不需要异步响应,会自动销毁sendResponse回调函数,释放相关内存,后续再调用该函数不会产生任何效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:15:05