Chrome 扩展 addListener 无法发送响应,因为端口为空

Chrome extension addListener unable to send response because port is null

有问题我可以绕过但是不明白为什么会这样!

正在尝试开发 chrome 扩展并将消息从弹出窗口发送到后台脚本 - 没问题。

但是在后台监听器中我无法发送响应,因为端口为空,只是因为我先调用了一个 chrome.storage 函数 - 为什么?

我有这个辅助功能:

gext.getsettings = function (callback)
{
  chrome.storage.local.get('settings', function(items) 
  {
    if(callback)
    {
      if(chrome.runtime.lastError)
        callback(false);

      if(items && items['settings']) 
        callback(items['settings']);
      else
        callback(null);
    }
  });
};

在 chrome.runtime.onMessage.addListener

中调用
gext.getsettings(function(settings)
{                  
          if(sendResponse)
            sendResponse({result: true});           
}

当我调试 sendResponse({result: true});我可以看到端口为空,因此失败。

我查到这是因为人们没有关闭端口,因此 Chrome 做到了,以便在第一次调用后关闭端口。 可以通过在之前的回调函数中 return 为真来绕过它。

在我的例子中,这有点复杂,因为我必须先调用回调,然后才能在 getsettings 中 return true - 但失败了。

我可以移动 sendResponse({result: true});在调用 getsettings 之前或之后退出,它工作正常。但是,如果我在发送响应之前依赖于某些特定设置怎么办 - 我该如何实现?

我知道我可以做一个永久开放的端口,但上面真的是设计使然吗?

我也有这个问题。理解为什么 port 是空的,当它应该被激活时,真的很烦人。

问题是当您在后台监听消息时,您应该始终在处理程序中 return true:这将使端口保持活动状态并指示您将发送响应稍后异步使用回调 sendResponse 函数。

例如:

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    handler(sendResponse); // a function which later will call sendResponse
    return true; // Important to return true, to keep the port alive
});

Find more details 来自 sendResponse 参数说明。