插件清单(Manifest)
浏览器扩展清单是浏览器扩展的蓝图。广义上讲,它是一个包含键值对的配置文件,这些键值对规定了扩展可以执行哪些操作以及以何种方式执行。
清单的内容会根据清单版本和浏览器的不同而有所差异。并非所有属性都能在所有浏览器中使用;一些浏览器可能只部分支持某个属性,甚至完全不支持。从清单v2到清单v3,会添加一些新属性,移除一些旧属性,还有一些属性的定义方式会发生变化。
MDN提供了一个非常好的清单属性支持情况表格,可以在此查看:
注意:本章省略了一些大多数网页浏览器不支持(如theme和theme_experiment)或完全未记录(如natively_connectable)的清单属性。
清单文件
浏览器扩展的清单定义在一个名为manifest.json
的文件中,该文件位于扩展的根目录下。这是浏览器扩展被视为有效所必需的唯一文件:
simple-extension-directory/
└─ manifest.json
注意:此文件是一个标准的JSON文件,但有一个显著的不同之处,即允许使用//
风格的注释。如果您的文本编辑器正在使用标准的JSON linter(代码检查工具),它可能会指示manifest.json
中不允许使用注释——请忽略此错误。所有浏览器和扩展商店都允许在清单中添加注释。
JSON文件包含一个对象,该对象包含大量配置扩展行为的必需和可选属性。其中只有三个必需属性:
manifest_version
:指示浏览器应如何解释清单。这对扩展的行为有很大影响。version
:声明扩展的版本号。扩展商店使用此信息来区分不同的发行版。name
:声明扩展的名称。浏览器和扩展商店都使用此名称作为扩展的顶级标识符。
因此,最简单的可能清单如下:
manifest.json
{
"name": "MVP扩展",
"version": "1.0",
"manifest_version": 3
}
支持不同的地区设置
清单中的多个属性定义了用户可见的字符串和文本图像。如果扩展需要根据用户的地区设置来支持多种语言,则硬编码这些值是不合适的。为了解决这个问题,清单支持根据用户的地区设置从消息文件中加载字符串。
要添加地区支持,必须将消息文件添加到_locales
目录中。该目录包含您希望支持的每种语言环境的子目录。在这些子目录中的每一个里面,都有一个messages.json
文件定义了本地化的字符串。然后,清单可以使用特殊的__MSG_messagename__
标识符自动加载这些字符串。
以下示例展示了一个支持英语和法语语言环境的简单目录结构:
localized-extension-directory/
├─ manifest.json
└─ _locales/
├─ en/ // 英语语言环境
│ └─ messages.json // 英语消息文件
└─ fr/ // 法语语言环境
└─ messages.json // 法语消息文件
清单文件将如下所示:
manifest.json
{
"name": "__MSG_extensionName__",
"version": "1.0",
"manifest_version": 3,
"default_locale": "en"
}
当使用地区设置功能时,清单文件中必须包含default_locale
属性。以下是messages.json
文件的格式要求:
_locales/en/messages.json
{
"extensionName": {
"message": "Hello world!"
}
}
_locales/fr/messages.json
{
"extensionName": {
"message": "Bonjour le monde!"
}
}
注意:地区设置和国际化是一个广泛且深入的主题。有关地区占位符、其他消息属性以及更多信息的详细信息,请参考Mozilla开发者网络文档。
注意:WebExtensions i18n API和扩展CSS文件也可以使用这些messages.json
文件中的地区字符串。有关详细信息,请参阅“扩展和浏览器API”章节。
匹配模式和通配符
清单中的多个属性可以使用匹配模式和通配符来一次性指定多个URL或文件。
文件路径匹配模式
诸如web_accessible_resources
等属性可以使用匹配模式来选择单个文件或整个目录。与清单文件中的所有文件路径一样,它们都是相对于扩展的根目录进行解析的。语法允许使用*
通配符来匹配零个或多个字符。以下是一些有效的文件匹配模式的示例:
/*
选择所有文件/foo/*
选择foo
目录中的所有文件/foo/*.png
选择foo
目录中的所有PNG文件/foo/bar.png
选择foo
目录中的一个PNG文件
URL匹配模式
content_scripts等属性可以使用匹配模式来将单个URL或整个网络来源加入白名单。该语法允许使用*通配符来匹配零个或多个字符。以下是一些有效的URL匹配模式的示例:
- "<all_urls>" 选择所有具有 http://、https://、ws://、wss://、ftp://、data:// 或 file:// 协议的 URL。
- "https://*/*" 选择所有具有 https:// 协议的 URL。
- "*://example.com/*" 选择所有具有 example.com 源的 URL。
- "https://example.com/foo/*" 选择所有具有 foo/ 路径前缀的 example.com URL。
- "https://example.com/foo/bar" 选择单个 URL。
注意:有关匹配模式规则的备注或具体详细信息,请参考
https://developer.chrome.com/docs/extensions/mv3/match_patterns/
URL 通配符
content_scripts 等属性可以使用通配符对 URL 匹配模式进行额外的筛选。通配符是 URL 匹配模式的扩展;其语法允许使用 * 通配符来匹配零个或多个字符,以及 ? 来匹配恰好一个字符:
- "*://example.com/*" 选择所有以 example.com 为来源的 URL
- "*://example.???/*" 选择所有以 example. 开头且顶级域名为三个字符的 URL,例如 example.com、example.org 和 example.gov
注意:有关通配符规则的备注或具体详细信息,请参考 https://developer.chrome.com/docs/extensions/mv3/content_scripts/#matchAndGlob
Manifest 属性
本节包含了一个全面的manifest属性列表以及它们的值应该如何定义。这些属性中的许多都与额外的浏览器权限或WebExtensions API的部分相关联;每个部分都会指导你到书中详细说明manifest属性值、所需权限和涉及API之间相互作用的部分。如果你想检查与解析manifest属性相关的浏览器源代码,请使用以下资源:
Chromium manifests: https://chromium.googlesource.com/chromium/src/+/main/chrome/common/extensions/api/_manifest_features.json
Firefox manifests: https://searchfox.org/mozilla-central/source/browser/components/extensions/schemas
提示:要在真实扩展中试验这些属性,您可以将它们添加到本章开头定义的“MVP扩展”manifest.json中。(其中许多属性需要额外的API、权限和文件才能工作。)请记住,对manifest的每次更改都需要重新加载扩展。
action
此属性定义了一个对象,其中包含决定浏览器工具栏中扩展图标行为和外观的值(图5-1)。这是manifest v3中browser_action和page_action属性的替代项。
注意:此属性仅可用于manifest v3。如果为manifest v2编写代码,请使用browser_action。
以下是一个包含完整示例值的属性展示:
manifest.json
文件中的action
属性
{
...
"action": {
"default_icon": {
"16": "icons/icon-16.png",
"32": "icons/icon-32.png",
"64": "icons/icon-64.png"
},
"default_popup": "popup/popup.html",
"default_title": "构建浏览器扩展",
"browser_style": true,
"theme_icons": [
{
"light": "icons/icon-16-light.png",
"dark": "icons/icon-16.png",
"size": 16
},
{
"light": "icons/icon-32-light.png",
"dark": "icons/icon-32.png",
"size": 32
}
]
},
...
}
action
对象允许包含以下属性:
default_icon
此属性通过指向图像文件的相对路径来指示浏览器工具栏图标的存放位置。定义此属性有两种方法:提供PNG或JPEG图像图标,并让浏览器智能地选择它偏好的图标;或者提供一个单一的矢量图像。提供一个或多个图像图标可以让浏览器根据当前的硬件配置决定哪个图标最合适。(例如,Apple Retina显示屏更喜欢分辨率加倍的图标。)提供16x16px、32x32px和64x64px的图标就足以覆盖所有可能的情况。以下是如何使用该属性的一个示例:
带有尺寸图像的default_icon
示例值
{
...
"action": {
"default_icon": {
"16": "icons/icon-16.png",
"32": "icons/icon-32.png",
"64": "icons/icon-64.png"
},
...
},
...
}
如果您想提供矢量图像,浏览器只需要一个矢量文件就可以适应所有的渲染配置:
带有矢量图像的default_icon
示例值
{
...
"action": {
"default_icon": "icons/icon.svg"
...
},
...
}
default_popup
此属性指示浏览器在点击扩展的工具栏图标时应定位哪个HTML文件以呈现为弹出窗口。这也可以通过WebExtension API的chrome.action.setPopup()
方法来设置或更改。以下是如何使用该属性的一个示例:
default_popup
的示例值
{
...
"action": {
"default_popup": "components/popup/popup.html"
...
},
...
}
注意 如果未定义此属性,当点击扩展的工具栏图标时,将不会出现弹出页面。相反,浏览器将在任何存在的后台脚本中分发一个点击事件。
default_title
此属性指定当鼠标悬停在扩展的工具栏图标上时,浏览器应显示的文本作为工具提示。还可以通过WebExtension API的chrome.action.setTitle()
方法来设置或更改此属性。以下是如何使用该属性的一个示例值:
default_title
的示例值
{
...
"action": {
"default_title": "打开资源管理器菜单"
...
},
...
}
注意:如果未定义此属性,浏览器将使用扩展的名称属性作为悬停文本。
browser_style
(仅Firefox)此属性是一个布尔值,用于告诉浏览器是否应在弹出窗口中注入样式表,以使其样式与浏览器保持一致。这些样式表可以在任何Firefox浏览器中通过访问chrome://browser/content/extension.css
(或在macOS上通过访问chrome://browser/content/extension-mac.css
)来查看。此属性的默认值为false。以下是如何使用该属性的一个示例值:
browser_style
的示例值
{
...
"action": {
"browser_style": true,
...
},
...
}
theme_icons
(仅Firefox)此属性允许您根据当前活动的Firefox主题定义备用图标,它有效地扩展了default_icon
的行为。以下是如何使用该属性的示例值:
{
...
"action": {
...,
"theme_icons": [
{
"light": "icons/icon-16-light.png",
"dark": "icons/icon-16.png",
"size": 16
},
{
"light": "icons/icon-32-light.png",
"dark": "icons/icon-32.png",
"size": 32
}],
...
},
...
}
author
此属性为在浏览器中显示的作者姓名提供信息。以下是如何使用该属性的示例值:
{
...
"author": "Matt Frisbie",
...
}
注意:如果定义了developer.name
属性,它将覆盖此值。
automation
(仅Chromium浏览器)此属性允许开发人员访问浏览器的可访问性树。此属性仅在扩展直接针对辅助设备时使用。根据MDN的说法,“浏览器根据DOM树创建可访问性树,平台特定的可访问性API使用该树来提供一种表示,这种表示可以被辅助技术(如屏幕阅读器)理解。”
注意:本书不涵盖支持可访问性的技术。有关如何使用此API的详细信息,请参阅Chrome开发者文档中的自动化扩展部分和Mozilla开发者网络中的可访问性树词汇表。
background
此属性允许您定义将用于背景脚本的文件或文件组。此属性在manifest v2和v3中均使用,但两个版本中该属性的值存在显著差异。
Manifest v2 背景脚本
在manifest v2中创建背景脚本的一种方法是在scripts数组中提供一个或多个脚本文件的引用。这些脚本将按其数组中的顺序加载。它们将在无头网页中加载,并且可以访问window对象和DOM。以下是如何以这种方式提供背景脚本的示例值:
背景脚本的示例值
{
...
"background": {
"scripts": [
"scripts/background-1.js",
"scripts/background-2.js"
]
},
...
}
Manifest v2 背景页
在Manifest v2中创建背景脚本的另一种方式是,提供一个指向包含<script>
标签的单个HTML文件的页面引用,这些<script>
标签用于加载背景脚本文件。此页面被渲染为一个无头网页,因此这些脚本将按照浏览器JavaScript引擎执行的顺序进行加载。以下是如何以这种方式提供背景脚本的示例:
背景页示例值
{
...
"background": {
"page": "background.html"
},
...
}
此策略具有多项优势。它允许用户通过添加type="module"
来使用import语句,还可以向无头HTML页面添加内容。
Manifest v2 持久页和事件页
除了定义背景脚本的加载方式外,background
属性还允许您通过布尔值persistent
属性定义脚本的执行方式。默认值为true:
- 当
persistent
为true时,会创建一个持久背景页。它始终保留在内存中。它在扩展加载或浏览器启动时启动,并一直持续到扩展卸载或浏览器关闭。 - 当
persistent
为false时,会创建一个非持久背景页。有时也称为“事件页”,当浏览器决定处于空闲状态时,可以随时卸载和重新加载此背景脚本。
以下是如何以这种方式提供背景脚本的示例:
持久背景页示例值
{
...
"background": {
"page": "background.html",
"persistent": true
},
...
}
Manifest v3 Service Worker
在Manifest v3中,创建背景脚本的选项要有限得多。由于Manifest v2中的持久页可能会消耗过多的系统资源,因此Manifest v3中的所有背景脚本都必须作为Service Worker执行。在Manifest v2中,与此最接近的是单个脚本事件页。
背景Service Worker示例值
{
...
"background": {
"service_worker": "scripts/background.js"
},
...
}
为了在背景脚本中使用import语句,可以添加"type": "module"
:
带模块脚本的背景Service Worker示例值
{
...
"background": {
"service_worker": "scripts/background.js",
"type": "module"
},
...
}
注意:有关设置背景脚本的详细信息,请参阅“背景脚本”章节。
browser_action
(仅Manifest v2)在Manifest v3中,browser_action
属性已被action
属性替代。这两个属性的值和行为实际上是相同的。如果您正在使用Manifest v2,请参考action
属性的详细说明来了解如何为此属性赋值。
注意:此属性是旧版浏览器扩展工具的一个遗留产物。在现代浏览器中,browser_action
和page_action
是冗余的。因此,这些属性已被合并为action
属性,其格式和行为与之相同。
browser_specific_settings
此属性定义了仅与某些浏览器相关的值。通常很少需要使用此属性。它采用一个对象的形式,该对象的键将值分配给特定的浏览器供应商。常见的键包括edge
、gecko
和safari
,它们分别对应于匹配这些供应商/引擎的浏览器。以下是如何使用此属性的一个示例:
browser_specific_settings的示例值
{
...
"browser_specific_settings": {
"edge": {
"browser_action_next_to_addressbar": false
},
"gecko": {
"id": "owner@example.com",
"strict_min_version": "51.0",
"strict_max_version": "62.*",
"update_url": "https://example.com/updates.json"
},
"safari": {
"strict_min_version": "21",
"strict_max_version": "28"
}
},
...
}
注意 Google Chrome不支持此键。
chrome_settings_overrides
此属性允许扩展程序覆盖某些浏览器界面的默认设置。其值是一个包含以下可选属性的对象:
homepage
:覆盖浏览器的默认主页。search_provider
:定义要添加到浏览器的新搜索引擎。startup_pages
:覆盖浏览器的默认启动页面。但请注意,这仅在基于Chromium的浏览器中受支持。
浏览器将在扩展管理界面中指示这些设置已应用(如图5-2所示)。
自定义主页
浏览器主页是当用户点击浏览器中的“主页”按钮时,浏览器将用户定向到的URL(如图5-3所示)。虽然所有主流浏览器默认不再显示主页按钮,但用户可以在浏览器的设置菜单中轻松启用它。主页URL可以按如下方式覆盖:
覆盖主页的示例值:
{
...
"chrome_settings_overrides": {
"homepage": "https://www.buildingbrowserextensions.com"
},
...
}
自定义搜索引擎
搜索引擎提供商决定了在浏览器地址栏中输入的查询将被发送到哪里。扩展程序可以通过searchTerms
访问查询字符串,将其插入到所选的URL中,并发送该URL(如图5-4、5-5、5-6、5-7所示)。
注意:浏览器的搜索引擎设置在浏览器启动时较早地初始化。您可能需要完全重启浏览器才能看到这些manifest文件中的更改生效。
自定义搜索引擎的覆盖方式:
覆盖search_provider的示例值:
{
...
"chrome_settings_overrides": {
"search_provider": {
"name": "Brave 搜索引擎",
"search_url": "https://search.brave.com/search?q={searchTerms}",
"encoding": "UTF-8",
"is_default": true
}
}
...
}
search_provider
对象还可以定义以下补充属性:
alternate_urls
:备用搜索URL列表,当主搜索URL不可用时使用。favicon_url
:搜索引擎的favicon(网站图标)URL。image_url
:用于搜索引擎结果的自定义图像URL模板。image_url_post_params
:发送到image_url
的POST参数。instant_url
:用于即时搜索结果的URL模板。instant_url_post_params
:发送到instant_url
的POST参数。keyword
:与此搜索提供程序关联的关键字(用于地址栏搜索)。prepopulated_id
:预填充搜索提供程序的ID(通常用于内部或默认搜索提供程序)。search_url_post_params
:发送到search_url
的POST参数。suggest_url
:用于获取搜索建议的URL模板。suggest_url_post_params
:发送到suggest_url
的POST参数。
注意:对这些补充属性的支持和文档可能有限,具体实现可能因浏览器而异。有关详细信息,请参阅Mozilla的WebExtensions文档
自定义启动页
(仅限Chromium浏览器)启动页是浏览器程序最初启动时打开的页面。扩展程序可以通过提供一个仅包含一个URL的数组来设置启动页(图5-8)。启动页URL可以按如下方式覆盖:
覆盖启动页的示例值:
{
...
"chrome_settings_overrides": {
"startup_pages": [
"https://www.buildingbrowserextensions.com"
]
},
... }
注意:chrome_
前缀与浏览器兼容性无关。此属性至少部分受到Chromium浏览器和Firefox的支持。
chrome_url_overrides
此属性允许扩展程序覆盖某些浏览器界面的默认页面。每个扩展程序只能覆盖以下浏览器页面中的一个:
- 历史记录页面
- 书签页面
- 新标签页页面
chrome_url_overrides
的值应该是一个对象,且仅包含以下属性之一:history
、bookmarks
、newtab
。以下是如何使用此属性的一个示例:
chrome_url_overrides
的示例值:
{
...
"chrome_url_overrides": {
"newtab": "components/newtab/newtab.html"
},
... }
注意:chrome_
前缀与浏览器的兼容性无关。此属性至少被Chromium浏览器和Firefox部分支持。
命令
此属性用于将键盘命令映射到扩展程序中的各种任务。例如,当用户按下Ctrl+Shift+F时,打开或关闭扩展程序的弹出窗口。而在JavaScript中映射多键命令需要为keydown或类似事件设置监听器,commands
属性则允许您使用简单直观的语法将多键键盘命令进行原生映射。您可以定义两种类型的命令:快捷键,它将键盘命令与一组预定义的浏览器原生行为相关联;或自定义命令,它将键盘命令与可以通过WebExtensions API处理的特殊事件相关联。
命令语法
所有命令都使用相同的语法。每个命令都采取具有两个属性的对象形式:suggested_key
对象,它定义了应调用命令的多键快捷键;以及description
字符串,它将在扩展程序的键盘快捷键管理用户界面(UI)中显示。以下是如何为通用foobar命令定义快捷键的示例:
通用foobar命令的示例值
{
...
"commands": {
"foobar": {
"suggested_key": {
"default": "Ctrl+Shift+F"
},
"description": "在当前页面上运行'foobar'。"
},
...
}
一旦扩展程序加载,浏览器将在其键盘快捷键管理UI中反映此快捷键(图5-9)。
注意:在Chromium浏览器中,快捷键列表位于chrome://extensions/shortcuts
,而在Firefox中,则位于about:addons
界面。
定义键盘快捷键
当定义键盘快捷键时,浏览器将监视指定的键组合,并在按下这些键时执行匹配的命令。以下可用的键标识符包括:
- 字母数字键:A-Z和0-9
- 常用键:逗号、句号、Home、End、PageUp、PageDown、空格、Insert、Delete
- 功能键:F1-F12
- 箭头键:上、下、左、右
- 媒体键:MediaNextTrack、MediaPlayPause、MediaPrevTrack、MediaStop
- 修饰键:Ctrl、Alt、Shift、MacCtrl(仅限macOS)、Command(仅限macOS)、Search(仅限ChromeOS)
键盘快捷键有以下限制:
- 键盘快捷键不能与浏览器的默认键组合重叠。例如,Ctrl+R已经被浏览器映射为重新加载页面,因此无法供扩展程序命令使用。
- 键盘快捷键必须由两个或三个键组成。
- 键盘快捷键必须包含Ctrl(或macOS上的MacCtrl)或Alt,但不能同时包含两者。
快捷键是通过将键标识符用加号(+)连接而成的字符串来定义的。一些有效的键盘快捷键示例包括:
- Ctrl+Shift+F
- Alt+Q
- MacCtrl+Shift+F12
- Alt+MediaPlayPause
多浏览器支持
suggested_key
对象至少应定义一个默认键盘快捷键。为了支持不同的操作系统,还可以定义以下属性:
- mac
- linux
- windows
- chromeos
- android
- ios
如果提供了这些值并且与主机操作系统匹配,浏览器将自动选择它们而不是默认值。
保留命令
浏览器会对某些命令名称进行特殊处理:
- 在manifest v3中,
_execute_action
将模拟点击扩展工具栏按钮的操作。 - 在manifest v2中,
_execute_page_action
将模拟点击扩展页面操作按钮的操作。 - 在manifest v2中,
_execute_browser_action
将模拟点击扩展浏览器操作按钮的操作。 - 在Firefox和manifest v2中,
_execute_sidebar_action
将打开扩展的侧边栏。
以下命令将在用户使用Ctrl+Shift+F快捷键时打开弹出窗口:
保留的_execute_action
命令的示例值
{
...
"commands": {
"_execute_action": {
"suggested_key": {
"default": "Ctrl+Shift+F"
}
}
},
... }
注意:当这些保留命令执行时,浏览器不会触发onCommand()
方法。
自定义命令
对于所有不匹配保留命令的命令标识符,快捷键将向command.onCommand()的所有监听器分发一个命令事件。 一个通用foobar命令的示例值
{
...
"commands": {"foobar": {
"建议的快捷键": {
"默认": "Ctrl+Shift+F"
},
"描述": "在当前页面上运行'foobar'。"
}
},
... }
上述的foobar命令将按如下方式处理:
chrome.commands.onCommand.addListener((command) => {
console.log(`命令: ${command}`); // 命令: foobar
});
全局命令
默认情况下,当浏览器未在设备上获得焦点时,键盘快捷键不会触发任何扩展命令。Chromium浏览器支持命令的可选全局属性,该属性允许即使浏览器未获得焦点,也触发仅使用与Ctrl+Shift+[0..9]匹配的快捷键的命令。以下是一个示例:
全局foobar命令的示例值
{
...
"commands": {
"foobar": {
"建议的快捷键": { "默认": "Ctrl+Shift+0" },
"描述": "在当前页面上运行'foobar'。",
"全局": true
},
...
}
}
注意:有关使用commands API的详细信息,请参阅扩展和浏览器API章节。
content_capabilities
此属性已过时,不应使用。在剪贴板API和持久存储API发布之前,它对于授予扩展访问剪贴板或无限存储的能力很有用。由于可以访问这些新的API,因此不再需要此属性。
content_scripts
该属性用于定义哪些文件应作为内容脚本被注入、注入的位置以及注入的方式。其值是一个对象数组,每个对象都定义了一组独立的内容脚本及这些脚本的注入规则。每个对象包含以下内容:
• matches
属性必须包含一个或多个 URL 匹配器的数组。与这些 URL 匹配器匹配的每个 URL 都会注入相应的脚本。此属性是必需的。
• js
和 css
属性分别包含一个或多个文件的数组,当页面 URL 匹配时,这些文件会被注入为内容脚本。应定义其中一个或两个属性。
• run_at
属性定义了内容脚本的注入时机。可以是 document_start
、document_end
或 document_idle
。默认值是 document_idle
。
document_start
:在document.readyState === "loading"
时注入脚本。document_end
:在document.readyState === "interactive"
时注入脚本。document_idle
:在document.readyState === "complete"
时注入脚本。
您还可以选择对 URL 应用以下三个附加过滤器:
• include_globs
属性可以定义为 URL 通配符的白名单。如果提供,则只有当 URL 与此通配符数组匹配时,才会注入内容脚本。
• exclude_matches
属性可以定义为 URL 匹配器的黑名单。如果提供,则只有当 URL 不与此匹配器数组匹配时,才会注入内容脚本。
• exclude_globs
属性可以定义为 URL 通配符的黑名单。如果提供,则只有当 URL 不与此通配符数组匹配时,才会注入内容脚本。
• match_about_blank
属性允许在 about:blank
或 about:srcdoc
URL 上注入内容脚本。
• all_frames
属性允许将内容脚本注入到嵌套框架中。
以下是一个关于如何使用 content_scripts
属性的示例:
content_scripts
的示例值:
{
...
"content_scripts": [
{
"matches": [
"*://example.com/*"
],
"include_globs": [
"*archive*"
],
"exclude_matches": [
"*://example.com/experimental/*"
],
"exclude_globs": [
"*?display=legacy*"
],
"js": [
"scripts/content-script.js"
],
"css": [
"styles/content-script.css"
],
"run_at": "document_end",
"match_about_blank": true,
"all_frames": true
}
],
...
}
提示:match_about_blank
键具有一些非常有趣的背景信息:https://stackoverflow.com/questions/41408936
注意:有关内容脚本的更多详细信息,请参阅“内容脚本”章节。
content_security_policy
此属性定义了扩展的内容安全策略(CSP)。在manifest v2和v3之间,此属性在结构和允许的值方面发生了重大变化。
Manifest v2的内容安全策略
Manifest v2的content_security_policy
属性是一个字符串,它为整个应用程序设置了CSP值。Manifest v2对CSP限制非常宽松:它允许自由执行诸如eval()
之类的脚本,这可能会产生安全漏洞。以下是此属性在manifest v2中的使用示例:
Manifest v2中content_security_policy的示例值
{
...
"content_security_policy": "script-src 'self' 'unsafe-eval' https://example.com; object-src 'self'",
...
}
Manifest v3的内容安全策略
Manifest v3显著改变了content_security_policy
的格式。此属性现在是一个对象,包含两个可能的键:
• extension_pages
:定义了所有非沙盒化扩展页面的CSP。
• sandbox
:定义了所有沙盒化扩展页面的CSP。
此外,在Chromium浏览器的Manifest v3中,禁止在非沙盒化扩展页面中使用某些CSP值,以防止执行诸如eval()
和第三方脚本执行等不安全操作。以下是此属性在manifest v3中的使用示例:
Manifest v3中content_security_policy的示例值
{
...
"content_security_policy": {
"extension_pages": "script-src 'self'",
"sandbox": "script-src 'self' https://example.com; object-src 'self'"
},
...
}
注意:有关扩展内容安全策略定义的详细信息,请参阅“扩展架构”章节。有关manifest v3中CSP限制的详细信息,请参考:Manifest V3迁移指南中的内容安全策略部分。
converted_from_user_script
此属性是谷歌在2016年支持从用户脚本过渡的一部分。其目的是使与Web扩展共享API的Chrome应用能够通过installReplacementWebApp()
方法引导其用户转向替代的渐进式Web应用。现代扩展将不会使用此属性。
注意:有关从Chrome应用过渡的更多信息,请访问:Chrome应用迁移指南。
cross_origin_embedder_policy
(仅适用于Chromium浏览器,仅manifest v3)此属性为向扩展源发出的请求定义了Cross-Origin-Embedder-Policy(COEP)头值。由于扩展在许多方面表现得像Web服务器,因此它可能易受到与Web服务器相同的基于同源的安全问题。如果您希望启用仅可通过跨源隔离访问的功能,则此属性用于设置COEP头值,以便以这种方式表现。要启用跨源隔离,此属性必须与cross_origin_opener_policy
属性一起设置。
此属性包含一个对象,该对象具有一个单值属性。以下是如何使用此属性来启用跨源隔离的示例:
cross_origin_embedder_policy 属性的示例值
{
...
"cross_origin_embedder_policy": {
"value": "require-corp"
},
...
}
注意:跨源隔离是本书范围之外的一个重要主题。有关此主题的精彩博客文章,请访问:Cross-Origin-Opener-Policy (COOP) 和 Cross-Origin-Embedder-Policy (COEP) 介绍。
cross_origin_opener_policy
(仅适用于Chromium浏览器,仅manifest v3)此属性为向扩展源发出的请求定义了Cross-Origin-Opener-Policy(COOP)头值。由于扩展在许多方面表现得像Web服务器,因此它可能易受到与Web服务器相同的基于同源的安全问题。如果您希望启用仅可通过跨源隔离访问的功能,则此属性用于设置COOP头值,以便以这种方式表现。要启用跨源隔离,此属性必须与cross_origin_embedder_policy
属性一起设置。
该属性包含一个对象,该对象具有一个单值属性。以下是如何使用此属性来(尽管实际上same-origin
值并不直接启用)实现跨源隔离的示例:
cross_origin_opener_policy
的示例值:
{
...
"cross_origin_opener_policy": {
"value": "same-origin"
},
...
}
注意:跨源隔离是本书范围之外的一个重要主题。要了解关于它的精彩博客文章,请访问https://web.dev/coop-coep/。
declarative_net_request
(仅适用于Manifest v3和Chromium浏览器)此属性定义了用于Declarative Net Request API的规则集。其值是一个对象,包含一个单一的rule_resources
键,该键定义了一个数组,数组中包含了扩展提供的所有规则集对象。每个规则集对象都必须定义一个唯一的id
字符串、一个enabled
布尔值(用于控制浏览器是否应使用该规则集),以及一个path
字符串(指向规则集JSON文件的相对路径)。以下是如何使用此属性的一个示例:
declarative_net_request
的示例值:
{
...
"declarative_net_request": {
"rule_resources": [
{
"id": "ruleset_1",
"enabled": true,
"path": "ruleset_1.json"
},
{
"id": "ruleset_2",
"enabled": false,
"path": "ruleset_1.json" /
}
]
},
...
}
注意: 有关Declarative Net Request API、规则集定义以及declarative_net_request权限的详细信息,请参阅网络章节。
default_locale
此属性定义默认区域设置字符串。当且仅当存在本章前面“区域设置”部分所述的_locales
目录时,此属性必须存在。以下是如何使用该属性的一个示例:
default_locale
的示例值
{
...
"default_locale": "en",
...
}
description
此属性定义了扩展的正式描述。该值在浏览器以及扩展市场中显示。以下是如何使用该属性的一个示例:
description
的示例值
{
...
"description": "一组浏览器扩展示例",
...
}
developer
此属性定义了一个对象,该对象包含要在浏览器中显示的作者姓名和/或扩展主页URL。name
和url
属性都是可选的。以下是如何使用该属性的一个示例:
developer
的示例值
{
...
"developer": {
"name": "Matt Frisbie",
"url": "https://www.buildingbrowserextensions.com"
},
...
}
注意:如果定义了developer
属性,它们将覆盖author
和homepage_url
属性。
devtools_page
此属性告诉浏览器你的扩展开发者工具内容的入口HTML文件的位置。这个页面用于启动开发者工具,但它呈现为一个无头页面(即不直接显示给用户的页面)。以下是如何使用该属性的一个示例:
devtools_page
的示例值
{
...
"devtools_page": "components/devtools/devtools.html",
...
}
注意:有关设置自定义开发者工具界面的详细信息,请参阅“Devtools Pages”章节。
differential_fingerprint
此属性是Chrome网上应用店用于扩展更新分发的内部密钥。在任何情况下,你都不应设置此属性。
注意:Chrome网上应用店在发送差异扩展更新时会生成此属性。此属性唯一标识该扩展新版本中发生更改的文件。在安装扩展时,会自动删除该密钥。
event_rules
(仅Chromium浏览器)此属性已弃用;它定义了使用declarativeWebRequest修改进行中的网络请求的规则,或根据页面内容执行操作——所有这些操作都无需使用declarativeContent读取页面内容的权限。由于declarativeWebRequest已被declarativeNetRequest取代,因此不应使用此属性。
externally_connectable
此属性定义了哪些外部扩展或网页可以通过runtime.connect()或runtime.sendMessage()方法与本扩展进行交互。如果未定义,则默认允许所有外部扩展通过这些方法通信,但禁止所有网页通过这些方法通信。属性值是一个对象,可以定义以下内容:
- 如果定义了ids数组,则只有具有匹配ID的扩展才能连接。此数组接受一个*通配符,以允许所有扩展。
- 如果定义了matches数组,则只有具有匹配URL的网页才能连接。
- 如果
accepts_tls_channel_id
属性设置为true
,则发出的消息中将包含TLS通道ID,以标识消息的来源框架。以下是如何使用该属性的一个示例:
externally_connectable
的示例值:
{
...
"externally_connectable": {
"ids": [
"allowmeabcdefabcdefabcdefabcdefa"
],
"matches": [
"https://*.example.com/*"
],
"accepts_tls_channel_id": true
},
...
}
file_browser_handlers
(仅Manifest v3及Chrome/Chrome OS)此属性定义了一个包含文件浏览器处理程序对象的数组,这些对象能够扩展Chrome OS的文件浏览器。此功能仅适用于Chrome OS设备。以下是如何使用该属性的示例值:
file_browser_handlers
的示例值:
{
...
"file_browser_handlers": [
{
"id": "upload",
"default_title": "保存文件",
"file_filters": [
"filesystem:*.*"
]
}
],
...
}
注意:Chrome OS文件浏览器处理程序不在本书的讨论范围内。有关文档,请参阅https://developer.chrome.com/docs/extensions/reference/fileBrowserHandler/。
file_system_provider_capabilities
(仅Manifest v3及Chrome/Chrome OS)此属性定义了一个对象,该对象包含决定扩展如何通过文件系统提供程序API与主机设备的文件系统交互的属性。此功能仅适用于Chrome OS设备。以下是如何使用该属性的示例值:
file_system_provider_capabilities
的示例值:
{
...
"file_system_provider_capabilities": {
"configurable": true,
"watchable": false,
"multiple_mounts": true,
"source": "network"
},
...
}
注意:Chrome OS的文件管理器和文件系统不在本书的讨论范围内。有关文档,请参阅https://developer.chrome.com/docs/extensions/reference/fileSystemProvider/。
homepage_url
此属性为浏览器中显示的扩展程序提供了一个主页URL。以下是如何使用该属性的示例:
homepage_url
的示例值:
{
...
"homepage_url": "https://www.buildingbrowserextensions.com"
...
}
注意:如果定义了developer.url
属性,它将覆盖homepage_url
的值。但请注意,在Chrome或Safari中不支持此覆盖行为。
host_permissions
(仅Manifest v3)此属性定义了扩展程序运行所需的主机匹配模式。如果网页与此列表中的一个或多个模式匹配,则扩展程序将能够读取或修改主机数据,如cookies、webRequest和tabs.executeScript。以下是如何使用该属性的示例:
host_permissions
的示例值:
{
...
"host_permissions": [
"*://developer.mozilla.org/*",
"*://developer.chrome.com/*"
],
...
}
重要的是,host_permissions
的值与content_scripts
的模式匹配器无关。控制哪些页面应该注入内容脚本的模式匹配器是在content_scripts
属性内定义的。
注意:有关扩展程序权限的详细信息,请参阅“权限”章节。
icons
该属性定义了一个对象,该对象包含决定扩展程序主要图标的值。这个图标在安装过程中以及在各个扩展程序市场(如Chrome Web Store)中都会被使用。至少,你应该定义一个128x128像素的光栅图像(JPEG、PNG、BMP或ICO格式)。如果你希望支持所有市场和浏览器,你应该定义四个PNG图像,尺寸分别为16x16、32x32、48x48和128x128像素。
以下是如何使用该属性的示例:
{
...
"icons": {
"16": "assets/icons/icon-16.png",
"32": "assets/icons/icon-32.png",
"48": "assets/icons/icon-48.png",
"128": "assets/icons/icon-128.png"
},
...
}
注意:此属性不支持SVG文件。
incognito
该属性允许你定义扩展程序如何与隐私浏览窗口进行交互。隐私浏览(也称为无痕浏览)是一种浏览器模式,它不会保存用户的浏览历史、搜索历史、下载历史、表单数据、cookies 或站点数据。对于希望在这种模式下提供功能或保持某些行为一致性的扩展程序来说,incognito
属性至关重要。
以下是如何使用该属性的示例:
{
...
"incognito": "spanning"
...
}
incognito
属性可以有以下三个值:
• spanning
允许扩展程序以相同方式处理隐私页面和非隐私页面。它可以通过 chrome.windows.getLastFocused()
方法来区分这两种页面。这是默认值。
• split
会将扩展程序分割成两个部分:一部分处理隐私页面,另一部分处理非隐私页面。这两个部分表现得像两个独立的扩展程序实例。
• not_allowed
在隐私浏览模式下禁用扩展程序。
注意:不同浏览器对 incognito
属性的支持程度有所不同,请参考 Chrome 扩展程序文档 和 Firefox WebExtensions 文档 以获取详细信息。
key
(仅 Chromium 浏览器)此属性为浏览器明确定义了 32 字符长度的扩展 ID 应为何值。如果不提供 key
,浏览器将自动为你生成它。
key
属性的示例值:
{
...
"key": "hdokiejnpivrijdhajhdlcegeplioahd"
...
}
注意:这仅在极少数情况下需要,即你希望在加载时进行本地开发时明确指定扩展程序的 ID。在部署到网页商店时,此值不会被使用。
manifest_version
此属性定义了浏览器应如何解释清单文件。如本章前文所述,此整数对整体清单文件的结构方式有着重要影响。以下是如何使用此属性的一个示例:
manifest_version
的示例值:
{
...
"manifest_version": 3
...
}
注意:一些浏览器,如 Firefox,仍在逐步推出对 manifest v3 的支持,但其他浏览器,如 Chrome,正在积极淘汰对 manifest v2 的支持。你的应用程序将需要生成多个 manifest.json
文件以支持多个市场。
minimum_chrome_version
(仅 Chromium 浏览器)此属性定义了扩展程序所需的最低 Chrome 版本。非 Chromium 浏览器将忽略此属性。以下是如何使用此属性的一个示例:
minimum_chrome_version
的示例值:
{
...
"minimum_chrome_version": "90"
...
}
nacl_modules
此属性曾用于 Native Client(NaCl)支持,但现在已被弃用。
注意:Native Client 是一个沙箱,用于在浏览器中高效且安全地运行编译后的 C 和 C++ 代码,且与用户的操作系统无关。它在 2020 年被弃用,并在 2021 年 6 月终止支持。
name
此属性定义了扩展程序的正式名称。此值将在浏览器中以及扩展程序市场显示。名称不应超过 45 个字符。以下是如何使用此属性的一个示例: 名称的示例值:
{
...
"name": "Building Browser Extensions",
...
}
oauth2
(仅 Chromium 浏览器)此属性用于将你的扩展程序注册为 OAuth2 客户端。其值是一个包含 OAuth2 客户端 ID 和作用域的对象:
optional_permissions 的示例值:
{
...
"oauth2": {
"client_id": "oAuthClientID.apps.googleusercontent.com",
"scopes": [
"https://www.googleapis.com/auth/contacts.readonly"
]
},
...
}
注意:有关为你的扩展程序设置身份验证的详细信息,请参阅“扩展程序和浏览器 API”章节。
offline_enabled
此属性已被弃用,不应再使用。在旧版代码库中,它曾用于指示扩展程序是否预期能在离线状态下工作。
omnibox
此属性通过定义其入口关键字来启用浏览器的原生地址栏(omnibox)接口。其值是一个包含单个 keyword
属性的对象。以下是如何使用此属性的一个示例:
omnibox
的示例值:
{
...
"omnibox": {
"keyword": "bbx",
},
...
}
假设用户已安装一个具有上述 omnibox 配置的扩展程序。omnibox 接口的工作流程如下:
- 用户将焦点放在浏览器的空地址栏上。
- 用户键入
bbx
后跟一个空格。 - 浏览器打开 omnibox 接口(如图 5-10 所示),此时用户可以开始输入与扩展程序相关的搜索或命令。
注意:扩展程序可以使用 Omnibox API 来控制地址栏(omnibox)的行为。这在“扩展程序和浏览器 API”章节中有深入讨论。
optional_host_permissions
(仅 Manifest v3 和 Chromium)此属性定义了扩展程序运行时不明确要求但用户可以选择的主机匹配模式。匹配模式的行为和语法与 host_permissions
相同。授予权限的用户界面与 optional_permissions
相同。
optional_permissions
此属性定义了扩展程序正确运行时不需要的权限,但它可以在运行时提示用户授予访问权限。此属性通常用于在后续发布中添加扩展程序权限,而无需要求所有用户授予对新权限的访问权限。并非所有权限类型都有资格出现在此数组中。以下是如何使用此属性的一个示例:
optional_permissions
的示例值:
{
...
"optional_permissions": [
"cookies",
"history",
"notifications"
],
...
}
注意:有关扩展程序权限的详细信息,请参阅“权限”章节。
options_page
这是一个已被弃用的属性,现在应使用 options_ui
来指定扩展程序的选项页面。
options_ui
这个属性告诉浏览器当通过程序、URL 或工具栏上下文菜单打开时,应该在哪里找到要呈现为选项页面的 HTML 文件。它是一个对象,通常只包含一个 page
属性,但在某些浏览器中也可能支持其他属性。
以下是如何使用 options_ui
属性的示例:
{
...
"options_ui": {
"page": "components/options/options.html"
},
...
}
browser_style
(仅 Firefox)这是一个布尔值属性,告诉浏览器是否应该在选项页面中注入样式表,以使其与浏览器的样式保持一致。这些样式表可以在任何 Firefox 浏览器中通过 chrome://browser/content/extension.css
(或在 macOS 上通过 chrome://browser/content/extension-mac.css
)查看。此属性的默认值为 false
。
以下是如何使用 browser_style
属性的示例:
{
...
"options_ui": {
"page": "components/options/options.html",
"browser_style": true,
},
...
}
open_in_tab
仅 Firefox)这是一个布尔值属性,告诉浏览器是否应该在普通的浏览器标签页中打开选项页面,而不是在嵌入的选项页面中(图 5-11)。此属性的默认值为 true
。
“以下是该属性如何使用的示例:
options_ui的示例值
{
...
'options_ui': {
'page': 'components/options/options.html',
'open_in_tab': false,
},
...
}
page_action
(Manifest v2专用)page_action
属性在Manifest v3中被action
属性取代。两者属性值和行为基本相同。若使用Manifest v2,请参考action
属性了解如何设置此属性的值。
注意:此属性是旧版浏览器扩展工具的一个遗留产物。在现代浏览器中,browser_action和page_action是冗余的。因此,这些属性已被合并到action属性中,该属性在格式和行为上都是相同的。
permissions
此属性定义了扩展正确运行所需的权限。所有权限类型均可加入此数组。在安装和更新时,添加到此数组的任何权限都将要求用户在弹出对话框中明确授予新权限的访问权。以下是如何使用此属性的示例:
permissions
的示例值
{
...
"permissions": [
"activeTab",
"declarativeNetRequest",
"geolocation"
],
...
}
在Manifest v2中,权限数组还包含了现在定义在host_permissions
属性中的URL模式匹配器。现代扩展现在应仅将URL模式匹配器放置在host_permissions
或optional_host_permissions
属性中。
注意:有关扩展权限的详细信息,请参阅“权限”章节。
platforms
此属性曾用于Native Client(NaCl)支持,现已弃用。
注意:Native Client是一个沙箱,用于在浏览器中高效且安全地运行编译后的C和C++代码,独立于用户的操作系统。它于2020年被弃用,并于2021年6月终止支持。
replacement_web_app
此属性是谷歌在2016年支持的从Chrome Apps过渡的一部分。其目的是让与Web扩展共享API的Chrome Apps能够通过installReplacementWebApp()
方法引导其用户到一个替代的渐进式Web应用(PWA)。现代扩展不会使用此属性。
注意:有关从Chrome Apps过渡的更多信息,请访问:
https://developer.chrome.com/docs/apps/migration/。
requirements
(仅适用于Chromium浏览器)此属性定义了扩展所需的浏览器技术。如果用户的设备不满足这些要求,Chrome网上应用店将通知他们,他们的设备缺少运行该扩展所需的技术。目前,唯一积极支持的属性是“3D”。以下是如何使用此属性的示例:
requirements
的示例值
{
...
"requirements": {
"3D": {
"features": [
"webgl"
]
}
},
...
}
sandbox
(仅适用于Chromium浏览器)此属性定义了哪些页面应以沙箱模式呈现。其值是一个对象,包含一个页面数组,该数组包含应以沙箱模式呈现的每个文件的路径。以下是如何使用此属性的示例:
sandbox
的示例值
{
...
"sandbox": {
"pages": [
"components/popup/popup.html",
"components/options/options.html",
]
},
...
}
注意:有关页面沙箱化的更多详细信息,请参阅“扩展架构”章节。
short_name
此属性定义了扩展的次要名称,该名称将在name
属性过长时使用。此名称不应超过12个字符。如果未提供,浏览器将简单地截断name
属性。以下是如何使用此属性的示例:
short_name
的示例值
{
...
"short_name": "BBX",
...
}
storage
此属性指定了管理存储的架构文件,该文件与storage.managed
API相关。以下是如何使用此属性的示例:
storage
的示例值
{
...
"storage": {
"managed_schema": "schema.json"
},
...
}
注意:浏览器对管理存储的处理方式有所不同。更多详细信息,请参阅“扩展和浏览器API”章节。
system_indicator
此属性已弃用,不应使用。
注意:有关此属性的历史记录,请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=142450。
tts_engine
(仅适用于Chromium浏览器)此属性用于声明扩展希望在浏览器的文本转语音引擎中使用的所有语音和语音配置。以下是如何使用此属性的示例:
tts_engine
的示例值
{
...
"tts_engine": {
"voices": [
{
"voice_name": "Alice",
"lang": "en-US",
"event_types": ["start", "marker", "end"]
},
{
"voice_name": "Pat",
"lang": "en-US",
"event_types": ["end"]
}
]
},
...
}
注意:有关Chrome的文本转语音API的详细信息,请参阅https://developer.chrome.com/docs/extensions/reference/ttsEngine/。
update_url
(仅适用于Chromium浏览器)此属性定义了浏览器应从哪个URL请求更新。它仅用于未托管在Chrome网上应用店的Chrome扩展。以下是如何使用此属性的示例:
update_url
的示例值
{
...
"update_url": "https://example.com/updates.xml",
...
}
注意:有关自托管扩展的详细信息,请参阅“扩展开发和部署”章节。
version
此属性定义了扩展的正式版本号。它用于唯一标识您的扩展的不同版本,并确定这些版本的顺序。浏览器对此值有不同的要求;例如,Chrome的版本验证器比Firefox更严格。为了简单和跨浏览器兼容性,强烈建议您遵循https://semver.org/描述的语义版本控制标准。以下是如何使用此属性的示例:
version
的示例值
{
...
"version": "1.5.0"
...
}
注意:使用MAJOR.MINOR、MAJOR.MINOR.PATCH或MAJOR.MINOR.PATCH.BUILD都是所有浏览器都会接受的版本格式。
version_name
此属性为扩展版本定义了一个描述符。它允许您添加如beta或rc1等句柄,这些句柄提供了有关发布的额外信息,但不符合浏览器的扩展版本验证器。以下是如何使用此属性的示例:
version_name
的示例值
{
...
"version_name": "1.5.0 beta"
...
}
web_accessible_resources
此属性定义了扩展中的哪些文件可以在扩展外部被访问,无论是网页还是其他扩展。扩展中的任何文件都有资格被列在这里,但该属性的目的是允许将扩展中的JS、CSS、HTML和图像文件添加到页面或外部扩展中。此属性在manifest v2和v3中都可以使用,但manifest v3规范为管理每个资源的访问控制列表添加了额外的控制。
Manifest v2
在manifest v2中,web_accessible_resources
的属性非常简单:只是一个模式字符串的数组。如果资源匹配此模式字符串,则网页或远程扩展将被授予读取访问权限。以下是如何使用此属性的示例:
Manifest v2中web_accessible_resources
的示例值
{
...
"web_accessible_resources": [
"scripts/widget.js",
"assets/images/*"
]
...
}
Manifest v3
Manifest v3扩展了此属性,以允许控制哪些来源或扩展可以访问某些资源,以及启用动态资源URL的选项。新格式是一个对象数组,具有以下属性:
resources
:匹配扩展中文件的模式列表。这相当于manifest v2中完整的web_accessible_resources
属性。此属性是必需的。matches
和extension_ids
:控制资源列表可在哪里访问。必须精确定义这两个属性中的一个。matches
是一个模式数组,匹配有资格访问资源列表的网页来源。extension_ids
是一个扩展ID数组,这些扩展ID有资格访问资源列表。use_dynamic_url
:一个布尔值,当为true时,将指示浏览器在每个会话中轮换资源的URL。此属性默认为false。由于扩展ID在扩展的整个生命周期内都是静态的,因此任何资源在发布之间默认情况下都将具有相同的URL。启用此属性会使该资源的URL变得不可预测。
总结
在本章中,您已经了解了清单(manifest)的作用以及如何创建它。本章带您了解了所有可能的清单属性、它们的功能、如何定义它们、它们与哪些API一起工作以及哪些浏览器可以使用它们。当您遇到清单属性时,应该能够参考本章的相关部分来快速了解该属性的作用。
下一章将介绍从manifest v2到v3的过渡。它将探讨这两个版本之间的差异以及它们将如何影响浏览器扩展的世界。