说明
使用 chrome.permissions API 在运行时(而非安装时)请求声明的可选权限,以便用户了解需要这些权限的原因,并仅授予必要的权限。
概念和用法
权限警告旨在说明 API 授予的功能,但其中一些警告可能并不明显。借助 Permissions API,开发者可以解释权限警告并逐步引入新功能,从而让用户在没有风险的情况下了解扩展程序。这样,用户就可以指定他们愿意授予的访问权限级别以及他们想要启用的功能。
例如,可选权限扩展程序的核心功能是覆盖新标签页。其中一项功能是显示用户当天的目标。此功能只需要存储权限,该权限不会触发警告。该扩展程序有一项额外功能,用户可以通过点击以下按钮来启用:
显示用户的热门网站需要 topSites 权限,该权限会显示以下警告。
topSites API 的扩展程序警告实现可选权限
第 1 步:确定哪些权限是必需的,哪些是可选的
扩展程序可以同时声明必需权限和可选权限。一般来说,您应该:
- 当扩展程序的基本功能需要使用某些权限时,请使用必需权限。
- 当扩展程序中的可选功能需要可选权限时,请使用可选权限。
必需权限的优势:
- 提示更少:扩展程序可以提示用户一次,让其接受所有权限。
- 开发更简单:保证存在所需权限。
可选权限的优势:
- 安全性更高:扩展程序运行时所需的权限更少,因为用户只需启用必要的权限。
- 为用户提供更清晰的信息:当用户启用相关功能时,扩展程序可以说明为何需要特定权限。
- 更轻松地升级:升级扩展程序时,如果升级添加的是可选权限而非必需权限,Chrome 不会为用户停用该扩展程序。
第 2 步:在清单中声明可选权限
使用 optional_permissions 键在扩展程序清单中声明可选权限,格式与 permissions 字段相同:
{
"name": "My extension",
...
"optional_permissions": ["tabs"],
"optional_host_permissions": ["https://www.google.com/"],
...
}
如果您想请求仅在运行时发现的主机,请在扩展程序的 optional_host_permissions 字段中添加 "https://*/*"。这样,您就可以在 "Permissions.origins" 中指定任何来源,只要其具有匹配的架构即可。
不能指定为可选的权限
大多数 Chrome 扩展程序权限都可以指定为可选,但以下情况除外。
| 权限 | 说明 |
|---|---|
"debugger" |
browser.debugger API 可作为 Chrome 远程调试协议的替代传输方式。 |
"declarativeNetRequest" |
向扩展程序授予对 browser.declarativeNetRequest API 的访问权限。 |
"devtools" |
允许扩展程序扩展 Chrome 开发者工具的功能。 |
"geolocation" |
允许扩展程序使用 HTML5 地理定位 API。 |
"mdns" |
授予扩展程序对 browser.mdns API 的访问权限。 |
"proxy" |
向扩展程序授予对 browser.proxy API 的访问权限,以便管理 Chrome 的代理设置。 |
"tts" |
browser.tts API 可播放合成的文字转语音 (TTS)。 |
"ttsEngine" |
browser.ttsEngine API 使用扩展程序实现文字转语音 (TTS) 引擎。 |
"wallpaper" |
仅限 ChromeOS。使用 browser.wallpaper API 更改 ChromeOS 壁纸。 |
如需详细了解可用权限及其警告,请参阅声明权限。
第 3 步:请求可选权限
使用 permissions.request() 在用户手势中请求权限:
document.querySelector('#my-button').addEventListener('click', (event) => {
// Permissions must be requested from inside a user gesture, like a button's
// click handler.
browser.permissions.request({
permissions: ['tabs'],
origins: ['https://www.google.com/']
}, (granted) => {
// The callback argument will be true if the user granted the permissions.
if (granted) {
doSomething();
} else {
doSomethingElse();
}
});
});
如果添加权限会导致出现与用户已看到并接受的警告消息不同的警告消息,Chrome 会提示用户。例如,上述代码可能会生成如下所示的提示:
第 4 步:查看扩展程序的当前权限
如需检查您的扩展程序是否具有特定权限或一组权限,请使用 permission.contains():
browser.permissions.contains({
permissions: ['tabs'],
origins: ['https://www.google.com/']
}, (result) => {
if (result) {
// The extension has the permissions.
} else {
// The extension doesn't have the permissions.
}
});
第 5 步:移除权限
当您不再需要这些权限时,应将其移除。移除权限后,调用 permissions.request() 通常会在不提示用户的情况下重新添加该权限。
browser.permissions.remove({
permissions: ['tabs'],
origins: ['https://www.google.com/']
}, (removed) => {
if (removed) {
// The permissions have been removed.
} else {
// The permissions have not been removed (e.g., you tried to remove
// required permissions).
}
});
类型
Permissions
属性
-
来源
string[] 可选
主机权限列表,包括清单中的
optional_permissions或permissions键中指定的权限,以及与内容脚本关联的权限。 -
权限
string[] 可选
已命名权限的列表(不包括主机或来源)。
方法
addHostAccessRequest()
browser.permissions.addHostAccessRequest(
request: object,
): Promise<void>
添加主机访问权限请求。只有在可以向扩展程序授予对请求中的主机的访问权限时,系统才会向用户发出请求。在跨域导航时,请求将被重置。接受后,授予对网站顶级源的永久访问权限
参数
-
request
对象
-
documentId
字符串 可选
可显示主机访问权限请求的文档的 ID。必须是标签页中的顶级文档。如果提供了此参数,请求会显示在指定文档的标签页上,并在文档导航到新来源时移除。添加新请求将覆盖
tabId的所有现有请求。必须指定此项或tabId。 -
图案
字符串 可选
可显示主机访问权限请求的网址格式。如果提供此字段,则主机访问请求将仅在与此格式匹配的网址上显示。
-
tabId
number 可选
可显示主机访问权限请求的标签页的 ID。如果提供了此参数,请求会显示在指定标签页中,并在标签页导航到新来源时被移除。添加新请求将覆盖“
documentId”的现有请求。必须指定此项或documentId。
-
返回
-
承诺<void>
contains()
browser.permissions.contains(
permissions: Permissions,
): Promise<boolean>
检查扩展程序是否具有指定权限。
参数
-
权限
返回
-
Promise<boolean>
Chrome 96 及更高版本 browser.*(自 Chrome 148 起)
返回
-
Promise<Permissions>
Chrome 96 及更高版本 browser.*(自 Chrome 148 起)
remove()
browser.permissions.remove(
permissions: Permissions,
): Promise<boolean>
移除对指定权限的访问权限。如果移除权限时出现任何问题,promise 将被拒绝。
参数
-
权限
返回
-
Promise<boolean>
Chrome 96 及更高版本 browser.*(自 Chrome 148 起)
removeHostAccessRequest()
browser.permissions.removeHostAccessRequest(
request: object,
): Promise<void>
移除主机访问权限请求(如果存在)。
参数
-
request
对象
-
documentId
字符串 可选
要移除主机访问权限请求的文档的 ID。必须是标签页中的顶级文档。必须指定此项或
tabId。 -
图案
字符串 可选
将移除主机访问权限请求的网址格式。如果提供,则必须与现有主机访问请求的模式完全匹配。
-
tabId
number 可选
要移除主机访问权限请求的标签页的 ID。必须指定此项或
documentId。
-
返回
-
承诺<void>
request()
browser.permissions.request(
permissions: Permissions,
): Promise<boolean>
请求访问指定权限,并在必要时向用户显示提示。这些权限必须在清单的 optional_permissions 字段中定义,或者必须是用户拒绝授予的必需权限。源格式中的路径会被忽略。您可以请求可选来源权限的子集;例如,如果您在清单的 optional_permissions 部分中指定 *://*\/*,则可以请求 http://example.com/。如果请求权限时出现任何问题,promise 将被拒绝。
参数
-
权限
返回
-
Promise<boolean>
Chrome 96 及更高版本 browser.*(自 Chrome 148 起)
事件
onAdded
browser.permissions.onAdded.addListener(
callback: function,
)
当扩展程序获取新权限时触发。
参数
-
callback
函数
callback参数如下所示:(permissions: Permissions) => void
-
权限
-
onRemoved
browser.permissions.onRemoved.addListener(
callback: function,
)
当扩展程序的权限访问权限被移除时触发。
参数
-
callback
函数
callback参数如下所示:(permissions: Permissions) => void
-
权限
-