简体   繁体   English

在内容脚本中使用 chrome.tabs 或其他 chrome API 时“无法读取未定义的属性”

[英]"Cannot read property of undefined" when using chrome.tabs or other chrome API in content script

chrome.tabs returns undefined despite the fact I set tabs in the permissions block.尽管我在权限块中设置了选项卡,但chrome.tabs返回未定义。

"permissions": [
    "tabs",
    "http://*/*",
    "https://*/*"
],
"content_scripts": [
    {
        "matches": [
            "http://*/*",
            "https://*/*"
        ],
        "js": [
            "js/myScript.js"
        ],
        "all_frames": true
    }
],

But in myScript.js the following returns undefined.但在 myScript.js 中,以下返回未定义。

chrome.tabs   

As content script has its own limitations,由于内容脚本有其自身的局限性,

chrome.tabs is only available in background scripts and popup scripts. chrome.tabs仅在后台脚本和弹出脚本中可用。

If you wanna to use chrome.tabs then pass message from content_script to background script and play with chrome.tabs .如果你想使用chrome.tabs然后将消息从 content_script 传递到后台脚本并使用chrome.tabs

Content scripts have only limited access to Chrome APIs.内容脚本对 Chrome API 的访问权限有限。 This access does not include the API you are trying to use (eg chrome.tabs ).此访问不包括您尝试使用的 API(例如chrome.tabs )。 If you need to use that API, you will have to do so in a background script 1 .如果您需要使用该 API,则必须在后台脚本1 中这样做。

As listed in Chrome's content scripts documentation , the APIs available to a content script are [I have placed deprecated methods in如 Chrome 的内容脚本文档中所列,内容脚本可用的 API 是 [我已将弃用的方法放在strikethrough删除线format]:格式]:

A couple of the listed APIs are deprecated and have been for some time.列出的几个 API 已被弃用,并且已经使用了一段时间。 Those that are deprecated have moved to different locations (also listed above):那些已弃用的已移至不同的位置(也在上面列出):

While not officially deprecated, extension.lastError is also available as runtime.lastError .虽然没有正式弃用,但extension.lastError也可以作为runtime.lastError At this point, it is usually referred to at that location:此时,通常在该位置引用:

Partition your extension into background scripts and content scripts将您的扩展程序划分为后台脚本和内容脚本

You are going to need to separate your code into what needs to be in a background script and what needs to be in content scripts, based on the capabilities available to each type of script.您将需要根据每种类型的脚本可用的功能将代码分为需要在后台脚本中的内容和需要在内容脚本中的内容。 Content scripts have access to the DOM of the web page into which they are injected, but limited access to extension APIs.内容脚本可以访问它们被注入到的网页的 DOM,但对扩展 API 的访问权限有限。 Background scripts have full access to the extension APIs, but no access to web page content.后台脚本可以完全访问扩展 API,但不能访问网页内容。 You should read the Chrome extension overview , and the pages linked from there, to get a feel for what functionality should be located in which type of script.您应该阅读Chrome 扩展概述以及从那里链接的页面,以了解应该在哪种类型的脚本中定位哪些功能。

It is common to need to communicate between your content scripts and background scripts.需要在内容脚本和后台脚本之间进行通信是很常见的。 To do so you can use message passing .为此,您可以使用消息传递 This allows you to communicate information between the two scripts to accomplish things which are not possible using only one type of script.这允许您在两个脚本之间传递信息,以完成仅使用一种脚本无法完成的任务。 For instance, in your content script, you may need information which is only available from one of the other Chrome APIs, or you need something to happen which can most appropriately (or only) be done through one of the other Chrome extension APIs.例如,在您的内容脚本中,您可能需要只能从其他 Chrome API 之一获得的信息,或者您需要发生一些最适合(或只能)通过其他 Chrome 扩展 API 之一完成的事情。 In these cases, you will need to send a message to your background script, using chrome.runtime.sendMessage() , to tell it what needs to be done, while providing enough informaiton for it to be able to do so.在这些情况下,您需要使用chrome.runtime.sendMessage()向后台脚本发送一条消息,告诉它需要做什么,同时提供足够的信息使其能够这样做。 Your background script can then return the desired information, if any, to your content script.然后,您的后台脚本可以将所需的信息(如果有)返回到您的内容脚本。 Alternately, you will have times when the processing will primarily be done in the background script.或者,有时处理将主要在后台脚本中完成。 The background script may inject a content script, or just message an already injected script, to obtain information from a page, or make changes to the web page.后台脚本可能会注入一个内容脚本,或者只是给一个已经注入的脚本发送消息,以从页面获取信息,或者对网页进行更改。


  1. Background script means any script that is in the background context.后台脚本是指在后台上下文中的任何脚本。 In addition to actual background scripts , this includes popups and options pages, etc. However, the only page that you can be sure to have consistently available to receive messages from a content script are your actual background scripts defined in manifest.json .除了实际的background脚本之外,这还包括弹出窗口和选项页面等。但是,您可以确保始终可用于从内容脚本接收消息的唯一页面是您在manifest.json 中定义的实际background脚本 Other pages may be available at some times as a result of the user's interaction with the browser, but they are not available consistently.由于用户与浏览器的交互,其他页面有时可能可用,但它们并非始终可用。

This answer was moved from a duplicate question , and then modified.这个答案是从一个重复的问题中移出来的,然后被修改了。

https://developer.chrome.com/extensions/tabs#method-getSelected shows https://developer.chrome.com/extensions/tabs#method-getSelected显示

getSelected被选中

chrome.tabs.getSelected(integer windowId, function callback) chrome.tabs.getSelected(整数windowId,函数回调)
Deprecated since Chrome 33. Please use tabs.query {active: true}.自 Chrome 33 起已弃用。请使用 tabs.query {active: true}。
Gets the tab that is selected in the specified window.获取在指定窗口中选择的选项卡。

Maybe, you should use chrome.tabs.query in popup.js like this也许,你应该像这样在popup.js 中使用 chrome.tabs.query

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    console.log(tabs[0].url);
});

, reload your extension and check the result in the inspect element of your extension. ,重新加载您的扩展程序并在扩展程序的检查元素中检查结果。

result image结果图像

code image代码图像

https://developer.chrome.com/extensions/tabs#type-Tab shows that The URL the tab is displaying. https://developer.chrome.com/extensions/tabs#type-Tab显示选项卡显示的 URL。 This property is only present if the extension's manifest includes the "tabs" permission.此属性仅在扩展程序的清单包含“tabs”权限时才存在。 (Just for remind someone forgot. I was forgot it when I just test it.) (只是为了提醒有人忘记了。我刚测试的时候就忘记了。)

Check this answer also https://stackoverflow.com/a/6718277/449345 This one worked for me也检查这个答案https://stackoverflow.com/a/6718277/449345这个对我有用

chrome.tabs.getSelected(null, function(tab){
    console.log(tab);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM