将消息传递给 Chrome 扩展内容脚本,而不将其指定为后台脚本

Pass message to Chrome extension content script without specifying it as a background script

我正在尝试向 Chrome 上下文菜单添加一项功能,以从所选文本添加待办事项。我从 background.js 的上下文菜单中传递选定的文本,如下所示:

function onClickHandler(info, tab) {
  chrome.extension.sendMessage(info.selectionText, function(){});
}

chrome.contextMenus.onClicked.addListener(onClickHandler);

chrome.runtime.onInstalled.addListener(function() {

  chrome.contextMenus.create({"title": "Add: %s", "contexts":["selection"]});

});

然后在 app.js 内容脚本中收听消息:

chrome.extension.onMessage.addListener(function(task, sender, sendResponse) {
  Task.setNewTask(task); // Saves the task in storage
});

当我的扩展程序在选项卡中打开时,消息会被正确接收,但当它关闭时,消息将无法正常工作。这是因为我没有在 manifest.json:

中将 app.js 设置为后台脚本
"permissions": [
    "storage",
    "contextMenus",
    "tabs",
    "notifications"
],

"background": {
  "scripts": ["background.js"]
}

我不将 app.js 作为后台脚本的原因是因为它包含我应用程序的其余代码,当尝试在后台 运行 时会产生错误而没有 DOM.

不幸的是,我无法轻松地在 background.js 文件中进行存储,因为我需要访问内容脚本中的函数 Task.setNewTask

我的应用程序有多种存储数据的方法,具体取决于环境——如果我必须将此逻辑放在 background.js 中,将会有很多重复。

我试过将我的应用程序作为背景页面:

"background": {
  "page": "index.html"
},

然后在页面底部包含两个脚本:

  <script src="background.js"></script>
  <script src="js/app.js"></script>
</body>

但是我的应用程序仍然不会在后台添加新任务。

有没有办法:

哦,亲爱的。您在哪里找到要修改的基本代码?

chrome.extension.sendMessage/chrome.extension.onMessage 已弃用 甚至不再出现在文档中。

但即使您将它们更改为适当的 chrome.runtime 等效项,与内容脚本通信仍然是错误的功能。

  1. 您的原始代码失败,因为 chrome.runtime.sendMessage(和 已弃用 chrome.extension 等效)仅发送到扩展页面(例如chrome-extension://yourid/ 起源),而不是内容脚本。

  2. 您修改的代码失败,因为消息传递永远不会将消息发送到 运行 来自的相同 JS 上下文。

您需要的是 chrome.tabs.sendMessage 函数,它允许您指定上下文脚本所在的选项卡。如果您想将它发送到当前选项卡,它会作为参数传递给 onClicked 侦听器。

function onClickHandler(info, tab) {
  chrome.tabs.sendMessage(tab.id, info.selectionText);
}

在上下文脚本方面,不要忘记更改为 chrome.runtime:

chrome.runtime.onMessage.addListener(function(task, sender, sendResponse) {
  Task.setNewTask(task); // Saves the task in storage
});