如果选项页面有 onMessage 侦听器,则内容脚本 sendMessage 会收到 null

Content scripts sendMessage receives null back if options page has onMessage listener

我有一个网络扩展插件,它由我的背景脚本、内容脚本和一个 options_ui 页面组成。 Content Scripts 使用 browser.runtime.sendMessage 向 Background script 发送消息,并期望从它那里获得所需信息的响应,这很常见。后台脚本使用 browser.runtime.onMessage.addListener.

进行监听

选项页面执行一个可能需要 1 到 5 分钟的操作,因此它告诉后台脚本执行此操作,并且后台脚本响应每 1% 更新一次进度到 browser.tabs.sendMessage。选项寻呼机注册一个 browser.runtime.onMessage 侦听器来侦听此更新。

问题是只要打开选项页面,内容脚本就无法从后台脚本接收任何响应。它得到的任何响应始终为空。后台脚本肯定会收到来自内容脚本的请求,并用正确的信息进行响应,但脚本不会收到响应。即使我打开了多个内容脚本,并且如果我按照我为选项页面所做的方式在每个内容脚本上注册一个 browser.runtime.onMessage 侦听器,只要关闭选项页面它就可以工作.

我不太确定这里发生了什么或接下来的步骤是什么。我知道 runtime.onMessage 的文档说,如果在同一文档上注册了两个侦听器,则只有一个侦听器可能会响应,但除非选项页面与后台脚本算作同一文档,否则这实际上没有意义。我知道这不仅仅是 Firefox 的问题,因为完全相同的行为也发生在 Chrome 中。

我找不到任何说明或记录选项页面也是页面的一部分的文档

Note: If multiple pages are listening for onMessage events, only the first to call sendResponse() for a particular event will succeed in sending the response. All other responses to that event will be ignored.

但如文档中所述

https://developer.chrome.com/extensions/messaging#connect

Long-lived connections

Sometimes it's useful to have a conversation that lasts longer than a single request and response. In this case, you can open a long-lived channel from your content script to an extension page , or vice versa, using runtime.connect or tabs.connect, respectively . The channel can optionally have a name, allowing you to distinguish between different types of connections.

您应该将 connect 用于您的用例