尽管我在权限块中设置了选项卡,但 chrome.tabs 仍返回未定义。\'permissions\': [ \'tabs\', \'http://*/*\', \'https://*/*\'],\'
chrome.tabs
尽管我在权限块中设置了选项卡,但仍然返回未定义。
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"matches": [
"http://*/*",
"https://*/*"
],
"js": [
"js/myScript.js"
],
"all_frames": true
}
],
但 myScript.js
, chrome.tabs
在 undefined
.
内容脚本 只能有限地访问 Chrome API。此访问不包括您尝试使用的 API(例如 chrome.tabs
)。如果您需要使用该 API,则必须在 后台脚本 1.
内容脚本文档 所列出的 ,内容脚本可用的 API 是[我已将弃用的方法以删除线格式放置]:
他们可以直接访问以下扩展 API:
- 主
- 国际化
- 贮存
- 运行时.connect()
- 运行时.getManifest()
- 运行时.getURL()
- 运行时标识
- 运行时.onConnect
- 运行时.onMessage
- 运行时.sendMessage()
chrome.tabs
对于 ,还有额外的困惑 chrome.tabs
。人们通常认为,因为它 .tabs
和内容脚本都在选项卡中,所以 chrome.tabs
在内容脚本中可用,但事实并非如此。
chrome.tabs 文档页面 chrome.tabs
documentation page 显示:
注意:服务工作线程和扩展页面可以使用 Tabs API,但不能用于内容脚本。
chrome.tabs.getCurrent()
文档 chrome.tabs.getCurrent()
混淆 更加严重了 :
获取此脚本调用所在的选项卡。如果从非选项卡上下文(例如,背景页面或弹出视图)调用,则返回未定义。
许多人认为提到“非选项卡上下文(例如,背景页面或弹出视图)”是指非背景上下文,但文档中具体指的是 实际的 背景页面,而不是背景上下文中的任何内容。它的意思是,为了返回选项 tab
,需要从背景上下文和选项卡上下文中的脚本调用它。如果它是从背景上下文中的脚本调用的,但不是在选项卡上下文中,那么它将返回 undefined
。它不适用于内容脚本上下文。尝试从内容 chrome.tabs.getCurrent()
脚本上下文调用将导致
未捕获的类型错误:无法读取未定义的属性
这是该问题所询问的错误。
您需要根据每种脚本可用的功能,将代码分为需要放在后台脚本中的代码和需要放在内容脚本中的代码。内容脚本可以访问它们被注入到的网页的 DOM,但对扩展 API 的访问权限有限。后台脚本可以完全访问扩展 API,但不能访问网页内容。您应该阅读 Chrome 扩展概述 以及 从那里链接的页面,以了解哪些功能应该位于哪种类型的脚本中。
内容脚本和后台脚本之间通常需要通信。为此,您可以使用 消息传递 。这允许您在两个脚本之间传递信息,以完成仅使用一种脚本无法完成的事情。例如,在您的内容脚本中,您可能需要只能从其他 Chrome API 之一获得的信息,或者您需要发生某些事情,而这些事情最合适(或只能)通过其他 Chrome 扩展 API 之一来完成。在这些情况下,您需要 发送一条消息 向您的后台脚本 chrome.runtime.sendMessage()
,告诉它需要做什么,同时提供足够的信息使其能够这样做。然后,您的后台脚本可以将所需的信息(如果有)返回给您的内容脚本。或者,有时处理主要在后台脚本中完成。后台脚本可能会注入内容脚本,或者只是向已注入的脚本发送消息,以从页面获取信息或对网页进行更改。
background
scripts ,这还包括弹出窗口和选项页面等。但是,唯一可以确保始终可用以接收内容脚本消息的页面是您 background
scripts 中定义的 后台脚本 。其他页面可能会因用户与浏览器的交互而有时可用,但它们并非始终可用。
This answer was moved from a 重复的问题 , and then modified.