参观 JavaScript 权限 API

如果你曾经创建了一个需要不同的功能的Web应用程序(如推送通知、网络摄像头访问、midi访问),你可能会注意到他们的API看起来非常不同。

1// for the geolocation API you need to call getCurrentPosition to check if geolocation is accessible
2navigator.geolocation.getCurrentPosition(gotLocation, didNotGetLocation);
3
4// for notifications we can directly check on the Notification object
5
6if (Notification.permission == 'granted')
7  // do notification stuff
8if (Notification.permission == 'denied')
9  // ask for notification access ....

这不是很方便的。

Permissions API允许我们对在我们的页面上可用的权限进行概述。我们用允许的意思是我们是否可以使用我们的代码访问特定功能。需要允许使用代码访问的功能称为强大的功能。

所有强大的功能的 API 都略有不同,因此,了解每个功能的权限状态可能很痛苦。

基本的 API 许可

允许API在这个阶段是非常实验性的,应该仔细使用。你只应该使用它,如果它是关键的任务,你可以跟上未来的破坏变化。例如,一些浏览器曾支持‘navigator.permissions.revoke’,但它现在已经过期。

在写作时,查询是我们可以从允许接口访问的唯一属性。查询作为一个称为 PermissionDescriptor的论点,使用一个对象。

1// This query will give us information about the permissions attached to the camera
2navigator.permissions.query({name: 'camera'})

该查询返回一个承诺,解决为PermissionStatus。PermissionStatus有两个字段:状态变更

1navigator.permissions.query({name: 'camera'}).then( permissionStatus => {
2  console.log(permissionStatus)
3  // in my browser on this page it logs:
4  //{
5  //   status: "prompt",
6  //   onchange: null,
7  // }
8})

状态有3种可能的状态:授予,拒绝提示授予意味着我们可以访问该功能,拒绝意味着我们无法访问该功能,提示意味着用户代理(即浏览器)将要求用户允许我们尝试访问该功能。

有些PermissionDescriptor有额外的字段,例如camera’s PermissionDescriptor有一个额外的字段,名为deviceId,如果您想瞄准特定摄像头,则您的查询可能看起来像: `.query({name: 'camera', deviceId: "my-device-id"})」。

「變更」是一個事件聆聽器,每當被查詢的功能的權限變更時,就會啟用。

 1navigator.permissions.query({name:'camera'}).then(res => {
 2  res.onchange = ((e)=>{
 3    // detecting if the event is a change
 4    if (e.type === 'change'){
 5      // checking what the new permissionStatus state is
 6      const newState = e.target.state
 7      if (newState === 'denied') {
 8        console.log('why did you decide to block us?')
 9      } else if (newState === 'granted') {
10        console.log('We will be together forever!')
11      } else {
12        console.log('Thanks for reverting things back to normal')
13      }
14    }
15  })
16})

所有 API 许可

有许多不同的强大的权限和浏览器支持是非常不均匀的。在下面的脚本中,你可以看到所有由W3C编辑的草案描述的权限(https://w3c.github.io/permissions/#permission-registry)在permissionsName变量中。getAllPermissions函数返回了各种可用的权限和他们的状态。请注意,结果将取决于您的浏览器,用户的偏好和网站的设置。

 1const permissionsNames = [
 2  "geolocation",
 3  "notifications",
 4  "push",
 5  "midi",
 6  "camera",
 7  "microphone",
 8  "speaker",
 9  "device-info",
10  "background-fetch",
11  "background-sync",
12  "bluetooth",
13  "persistent-storage",
14  "ambient-light-sensor",
15  "accelerometer",
16  "gyroscope",
17  "magnetometer",
18  "clipboard",
19  "display-capture",
20  "nfc"
21]
22
23const getAllPermissions = async () => {
24  const allPermissions = []
25  // We use Promise.all to wait until all the permission queries are resolved
26  await Promise.all(
27    permissionsNames.map(async permissionName => {
28        try {
29          let permission
30          switch (permissionName) {
31            case 'push':
32              // Not necessary but right now Chrome only supports push messages with notifications
33              permission = await navigator.permissions.query({name: permissionName, userVisibleOnly: true})
34              break
35            default:
36              permission = await navigator.permissions.query({name: permissionName})
37          }
38          console.log(permission)
39          allPermissions.push({permissionName, state: permission.state})
40        }
41        catch(e){
42          allPermissions.push({permissionName, state: 'error', errorMessage: e.toString()})
43        }
44    })
45  )
46  return allPermissions
47}

如果我在Alligator.io上的开发者控制台中运行以下代码:

1(async function () {
2  const allPermissions = await getAllPermissions()
3  console.log(allPermissions)
4})()

以下是我在控制台上得到的屏幕截图:

工人许可证

到目前为止,我们只使用navigator.permissions API,因为编写简要的示例要容易得多。

希望您现在能够更好地了解如何使用 Permissions API. 它并不复杂,也不是必不可少的,但它确实使我们更容易在基于JavaScript的应用程序中管理权限。

Published At
Categories with 技术
Tagged with
comments powered by Disqus