You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何检查runtime.lastError会触发Chrome扩展的端口错误?

解决Chrome扩展中sendMessage带回调时的端口关闭错误

我之前也碰到过这个诡异的问题,折腾了好一阵才搞明白根源!咱们一步步拆解:

问题原因

当你给chrome.runtime.sendMessage加上回调函数时,Chrome的消息机制会默认认为你需要后台脚本给一个响应——它会建立一个临时的消息端口,等待后台通过sendResponse方法完成这次交互。

如果你的后台监听器既没调用sendResponse,也没在同步执行阶段返回true(表示要异步回复),那么监听器执行完之后,Chrome会立刻关闭这个端口。这时候前端的回调就会触发lastError,也就是你看到的The message port closed before a response was received错误。

你提到的返回true只是延迟错误,也很好解释:返回true是告诉Chrome“我稍后会异步调用sendResponse,先别关端口”,但如果你最终根本没调用sendResponse,Chrome过一会儿还是会强制关闭端口,错误依然会出现。

解决方案

因为你明确说这是单向消息,不需要后台返回响应,所以有两种靠谱的处理方式:

1. 直接使用无回调的sendMessage(推荐)

就像你已经测试的那样,去掉回调函数:

// options.js 无报错版本,完美适配单向消息场景
chrome.runtime.sendMessage({ hello: true });

这种情况下,Chrome不会建立需要响应的端口,自然不会触发任何错误,完全符合你的需求。

2. 如果必须用回调(比如要做发送确认)

那就在后台监听器里主动调用sendResponse,哪怕只是传个空值,告诉Chrome“我收到消息了,这次交互结束”:
修改你的background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (typeof request.hello !== "undefined") {
    console.log("I got it!");
    sendResponse(); // 主动完成消息交互,避免端口报错
  }
});

这样前端带回调的调用就不会再报错了,因为Chrome收到了明确的响应信号,端口会正常关闭。

额外提醒

别用return true来应付这个问题,除非你真的有异步回复的需求(比如要等某个API请求完成再回复)。如果只是单向消息,要么用无回调的调用,要么主动调用sendResponse,这才是规范的做法。

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

火山引擎 最新活动