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

查看:99
本文介绍了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"
}

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

非常感谢任何帮助!谢谢.

Any help is massively appreciated! Thanks.

推荐答案

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

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天全站免登陆