Chrome扩展程序消息传递不起作用(background.js到content.js)

时间:2020-09-18 18:42:29

标签: javascript google-chrome-extension messaging chrome-native-messaging

我竭尽全力试图弄清楚为什么我的Chrome扩展程序无法传递消息。

请紧记,上个月我绝对是javascript的新手,并且我一直在网上自学视频(我的编码背景完全是java)。

我想要的是让我的后台脚本能够将发生的事情通知我的内容脚本,然后在内容脚本中执行一些代码。正如您在下面看到的,I have set up my code identically to the documentation,但是它不起作用!

以下是我在加载扩展程序时遇到的错误:

Errors

manifest.json

{
   "content_scripts": [
      {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
      }
   ],

   "background": {
      "scripts": ["background.js"],
      "persistent": true
    },

   "permissions": [
      "activeTab",
      "tabs",
      "storage"
   ],

   "manifest_version": 2,
   "name": "eSports YT Viewer",
   "version": "1.0.0",
   "description": "An eSports viewer for youtube"
}

background.js

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
   chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
      console.log(response.farewell);
   });
});

content.js

chrome.runtime.onMessage.addListener(
   function(request, sender, sendResponse) {
      console.log(sender.tab ?
      "from a content script:" + sender.tab.url :
      "from the extension");
      if (request.greeting == "hello") {
         sendResponse({farewell: "goodbye"});
      }
});

我们非常感谢您的帮助!谢谢。

2 个答案:

答案 0 :(得分:0)

您当前的后台脚本是错误的,或者没有做任何有意义的/有用的事情。后台脚本在单独的隐藏后台页面中运行。另请参见Accessing console and devtools of extension's background.js

当a)浏览器配置文件启动,b)重新启用/重新加载扩展程序或c)安装时,运行持久性后台脚本。因此,您的代码会立即查询选项卡,并将消息发送到任何处于活动状态的选项卡,因此无法保证它甚至包含一个网页:不能有任何内容(空白的新选项卡),也可以是内部chrome://页面(用于浏览器设置)或选项卡可能仍在等待内容脚本执行(请参阅此答案末尾的注释)。

将后台脚本切换为"persistent": false也无济于事。它只会使脚本在API事件或打开弹出窗口时唤醒,但是您没有注册任何API事件,也没有声明弹出窗口。无论如何,除了different reason之外,您都应该切换到"persistent": false:使其仅按需运行。

解决方案

后台脚本的通常用途是为chrome API事件注册处理程序,例如chrome.tabs.onUpdated或chrome.webNavigation.onHistoryStateUpdated等,否则很有可能不需要背景脚本。在事件处理程序中,您可以将消息发送到选项卡。许多人错误地将其发送到活动选项卡,但通常没有意义,因为该事件可能发生在非活动/背景选项卡中。通常,您应该将其发送到生成事件的选项卡,在传递给处理程序的参数中查找tabtabId,并在这些事件上引用documentation

还请注意,默认情况下,内容脚本在DOMContentLoaded之后运行,因此,如果在页面仍在加载时发送消息,它将失败。在这种情况下,您可以在document_start上运行它们,也可以使用其他方法,例如不要声明内容脚本,而是以编程方式注入它。没有通用答案,这取决于用例。

如果您确实需要在扩展名启动/重新启动时向内容脚本发送消息,则必须首先通过chrome.tabs.reload(这样内容脚本将自动运行)或{{3 }}。

答案 1 :(得分:-1)

从您在帖子中看到的所有内容来看,一切看起来都是井井有条的,所以我只是抛出一些想法:

我认为这里错误的线索是第一个错误,而不是第二个-看起来脚本之间的通信还没有established correctly

可能尝试将背景脚本的persistent设置更改为false:

"background": {
  "scripts": ["background.js"],
  "persistent": false
},

From the docs,仅当您使用chrome.webRequest API修改网络请求时才需要,并且可能会引起此处设置的奇怪问题。

但正如我所说,只是初步猜测。

祝你好运!