Chrome扩展程序消息传递不起作用(background.js到content.js) [英] Chrome extension message passing not working (background.js to content.js)

查看:680
本文介绍了Chrome扩展程序消息传递不起作用(background.js到content.js)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am at my wits end with trying to figure out why I can't get message passing to work in my Chrome extension.

请记住,在过去的一个月中,我绝对不是javascript的新手,并且我一直在自学在线视频(我的编码背景完全是java).

Keep in mind, I am absolutely brand new to javascript within the last month and I've been teaching myself with videos online (my coding background is exclusively java).

我想要的是让我的后台脚本能够将发生的事情通知我的内容脚本,然后在内容脚本中执行一些代码.正如您在下面看到的那样,我已经将代码设置为与文档相同,但是不起作用!

All I want is for my background script to be able to notify my content script of something happening and then subsequently have some code execute within the content script. As you can see below, I have set up my code identically to the documentation, and yet it's not working!

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

Here are the errors that I am getting when I load the extension:

错误

manifest.json

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

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

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"});
      }
});

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

Any help is massively appreciated! Thanks.

推荐答案

您当前的后台脚本是错误的,或者没有做任何有意义的/有用的事情.后台脚本在单独的隐藏后台页面中运行.另请参见访问扩展程序background.js的控制台和devtools.

Your current background script is wrong or rather doesn't do anything meaningful/useful. The background script runs in a separate hidden background page. See also Accessing console and devtools of extension's background.js.

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

A persistent background script runs when a) the browser profile starts, b) when the extension is re-enabled/re-loaded, or c) installed. So, your code immediately queries the tabs and sends a message to whatever tab is active, hence there's no guarantee it even contains a web page: there can be nothing (an empty new tab) or it can be an internal chrome:// page for browser settings or the tab may still be pending content script execution (see the note at the end of this answer).

将后台脚本切换为"persistent": false也无济于事.它只会使脚本在API事件或打开弹出窗口时唤醒,但您没有注册任何API事件,也没有声明弹出窗口.无论如何,您都应该切换到"persistent": false,但要使用不同的原因:仅使其运行在需求.

Switching the background script to "persistent": false won't help you either. It will only make the script wake up on an API event or when the popup is opened, but you're not registering any API events nor have you declared a popup. You should switch to "persistent": false anyway but for a different reason: to have it running only on demand.

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

The usual purpose of the background script is to register handlers for chrome API events such as chrome.tabs.onUpdated or chrome.webNavigation.onHistoryStateUpdated and so on, otherwise it's highly probable you don't need the background script at all. In the event handler you can send a message to the tab. A lot of people mistakenly send it to the active tab but usually it doesn't make sense as the event may have occurred in an inactive/backgrounded tab. Usually you should send it to the tab that generated the event, look for tab or tabId in the parameter passed to the handler, refer to the documentation on those events.

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

Also note that the content scripts run after DOMContentLoaded by default so if you send a message while the page is still loading it'll fail. In that case you can either run them at document_start or use a different approach e.g. don't declare a content script but rather inject it programmatically. There's no universal answer, it depends on the use case.

如果确实需要在扩展名启动/重新启动时向内容脚本发送消息,则必须首先通过chrome.tabs.reload重新加载所有匹配的选项卡(这样内容脚本将自动运行)或明确地注入脚本.

If you really need to send a message to the content script on extension startup/restart then you'll have to reload all matching tabs first via chrome.tabs.reload (so the content scripts will run automatically) or reinject the scripts explicitly.

这篇关于Chrome扩展程序消息传递不起作用(background.js到content.js)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆