使用权限 API
本文提供了使用 W3C 权限 API 的基本指南,该 API 提供了一种以编程方式查询与当前上下文相关的 API 权限状态的方法。
请求权限的麻烦…
Web 上的权限是必要的,但对于开发人员来说,它们并不令人愉快。
在过去,不同的 API 以不一致的方式处理它们自己的权限 - 例如 通知 API 有自己用于检查权限状态和请求权限的方法,而 地理位置 API 则没有。
权限 API 为开发人员提供了一种一致的方法,并允许他们在权限方面实现更好的用户体验。具体来说,开发人员可以使用 Permissions.query()
检查在当前上下文中是否授予了使用特定 API 的权限,是否被拒绝,或者是否需要通过提示获取特定用户的权限。在主线程中查询权限 得到广泛支持,在 工作线程 中也得到支持(有一个明显的例外)。
许多 API 现在支持权限查询,例如 剪贴板 API、通知 API、推送 API 和 Web MIDI API。在 API 概述 中提供了许多支持权限的 API 列表,您可以在 此处的兼容性表 中了解浏览器支持情况。
Permissions
有其他方法可以专门请求使用 API 的权限,以及撤销权限,但这些方法已弃用(非标准,或者没有得到广泛支持)。
一个简单的例子
对于本文,我们创建了一个名为 Location Finder 的简单演示。它使用地理位置查询用户的当前位置,并在 Google 地图上标出。
您可以 在线运行示例,或 在 GitHub 上查看源代码。大多数代码很简单,下面我们将介绍与权限 API 相关的代码,如果您想研究其他部分,请查看代码本身。
访问权限 API
已向浏览器添加了 Navigator.permissions
属性,以允许访问全局 Permissions
对象。此对象最终将包含用于查询、请求和撤销权限的方法,但目前它只包含 Permissions.query()
;请参见下文。
查询权限状态
在我们的示例中,权限功能由一个函数处理 - handlePermission()
。它首先使用 Permissions.query()
查询权限状态。根据 promise 解决时返回的 PermissionStatus
对象的 state
属性的值,它将以不同的方式做出反应。
"granted"
-
“启用地理位置”按钮被隐藏,因为如果地理位置已处于活动状态,则不需要它。
"prompt"
-
“启用地理位置”按钮被隐藏,因为如果用户将被提示授予地理位置权限,则不需要它。然后运行
Geolocation.getCurrentPosition()
函数,该函数会提示用户授予权限;如果授予权限,它会运行revealPosition()
函数(显示地图),如果拒绝权限,它会运行positionDenied()
函数(使“启用地理位置”按钮出现)。 "denied"
-
“启用地理位置”按钮被显示出来(如果页面首次加载时权限状态已设置为拒绝该来源,则此代码也需要在这里)。
function handlePermission() {
navigator.permissions.query({ name: "geolocation" }).then((result) => {
if (result.state === "granted") {
report(result.state);
geoBtn.style.display = "none";
} else if (result.state === "prompt") {
report(result.state);
geoBtn.style.display = "none";
navigator.geolocation.getCurrentPosition(
revealPosition,
positionDenied,
geoSettings,
);
} else if (result.state === "denied") {
report(result.state);
geoBtn.style.display = "inline";
}
result.addEventListener("change", () => {
report(result.state);
});
});
}
function report(state) {
console.log(`Permission ${state}`);
}
handlePermission();
权限描述符
Permissions.query()
方法将一个 PermissionDescriptor
字典作为参数 - 它包含您感兴趣的 API 的名称。一些 API 有更复杂的 PermissionDescriptor
,包含其他信息,这些信息继承自默认的 PermissionDescriptor
。例如,PushPermissionDescriptor
还应包含一个布尔值,用于指定 userVisibleOnly
为 true
还是 false
。
响应权限状态更改
您会注意到,我们在上面的代码中监听了 change
事件,并将其附加到 PermissionStatus
对象 - 这使我们能够响应我们感兴趣的 API 的权限状态的任何更改。目前我们只是报告状态变化。
结论和未来工作
目前这并没有比我们已经拥有的提供更多内容。如果我们选择从权限提示中永远不共享我们的位置(拒绝权限),那么我们就无法回到权限提示,除非使用浏览器菜单选项。
- Firefox:工具 > 页面信息 > 权限 > 访问您的位置。选择始终询问。
- Chrome:汉堡菜单 > 设置 > 显示高级设置。在隐私部分,点击内容设置。在弹出的对话框中,找到位置部分,选择当网站尝试时询问...。最后,点击管理例外情况,并删除您授予给相关网站的权限。
有一些提案,希望能够让网站能够以命令的方式 请求 和 撤销 权限,但进展不大,因为用例不明确,并且遭到了浏览器厂商的反对。请参见有关 从主要规范中删除 permissions.request()
和 从主要规范中删除 permissions.revoke()
的讨论。