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

Chrome扩展报错:‘消息端口在收到响应前已关闭’的解决方法

解决Chrome扩展中“The message port closed before a response was received”错误

问题背景

我在开发Chrome扩展时,通过chrome.runtime.sendMessage从内容脚本向后台脚本传递参数发起POST请求,后台脚本处理完请求后想用sendResponse向内容脚本返回结果,但始终触发“The message port closed before a response was received”错误。

原后台脚本代码

chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  let res = await fetch(message.endpoint, {
    'method': 'POST',
    'headers': message.headers,
    'body': message.body
  })
  let json = await res.json();
  console.log('json data:' + json);
  sendResponse({
    'status': true,
    'url': json.url
  });
});

原内容脚本代码

chrome.runtime.sendMessage({
  endpoint: 'https://example.com/api',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
}, (response) => {
  console.log(response);
});

我已经尝试在chrome.runtime.onMessage监听器末尾添加return true,但问题仍未解决。


解决方案

通过调整消息传递方式解决了该问题,具体修改如下:

修改后的内容脚本

// 向后台脚本发送请求
chrome.runtime.sendMessage({
  endpoint: 'https://example.com/api',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
}, (response) => {
  console.log(response);
});

// 监听来自后台脚本的响应消息
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.message === "audio_url") {
    console.log('audio_url:' + request.audio_url);
    sendResponse({
        'status': true,
    });
  }
});

修改后的后台脚本

// 监听内容脚本的请求
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
  // 先返回一个空响应关闭初始消息端口
  sendResponse({ 'status': true });
  // 处理POST请求
  let res = await fetch(message.endpoint, {
    'method': 'POST',
    'headers': message.headers,
    'body': message.body
  });
  let json = await res.json();
  console.log('json data:' + json);
  console.log('url:' + json.url);
  
  // 确保能获取到当前tab的ID
  if (sender.tab === undefined || sender.tab.id === undefined) return;
  
  // 通过chrome.tabs.sendMessage向内容脚本发送处理结果
  chrome.tabs.sendMessage(sender.tab.id, { message: "audio_url", audio_url: json.url }, function (response) {
    console.log(`status:`, response.status);
  });
  return true;
});

问题原因分析

原方案中直接用sendResponse返回异步处理结果会导致消息端口提前关闭,因为sendResponse在异步操作完成前就失去了有效上下文。另外,runtime.sendMessage的响应机制不适合传递异步处理后的结果到内容脚本,改用chrome.tabs.sendMessage可以直接从后台脚本主动向内容脚本发送消息,绕过原有的消息端口限制,避免端口关闭错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:25:29