JavaScript 权限 API 介绍

如果你曾经做过需要申请权限的应用(推送通知,访问摄像头,音频设备等),你可能注意到了,它们的 API 看起来不太一样。 // 对于定位 API ,需要调用 getCurrentPosition 来检查定位信息是否可用 navigator.geolocation.getCurrentPosition(gotLocation, didNotGetLocation); // 对于消息通知,我们可以直接检查 Notification 对象 if (Notification.permission == 'granted') // 授权后的逻辑 if (Notification.permission == 'denied') // 请求授权 这显然不太方便。 权限 API 让我们可以查看页面上可用的权限。我们说的“权限”是指在代码里能否访问某个特性。需要用代码通过权限访问的特性称为“强力特性”。摄像头、音频设备接口(midi)、通知、地理位置等都是强力特性。 所有强力特性的 API 都有细微的差别。因此,要弄清楚每个特性的权限状态可能很麻烦。有了权限 API,我们可以通过单个接口管理所有权限的状态。 权限 API 基本概念 权限 API 目前还处于试验阶段,需要谨慎使用。只有在你能跟上破坏性的特性变化时才能在关键业务上使用它。例如,一些浏览器曾经支持 navigator.permissions.revoke ,但现在已经弃用了。 写这篇文章的时候, query是permissions接口里唯一可用的属性。query 接受一个叫做PermissionDescriptor的对象参数。该对象有个字段叫name,就是你要访问的权限名称。 // 该查询返回摄像头的权限信息 navigator.permissions.query({name: 'camera'}); 查询返回一个 promise,resolve 结果是一个 PermissionStatus。它有两个字段:state 和 onchange。 navigator.permissions.query({name: 'camera'}).then( permissionStatus => { console.log(permissionStatus); // 我的浏览器控制台输出: //{ // state: "prompt", // onchange: null, // } }) state 有 3 个可能的值:granted,denied 和 prompt。granted 表示允许访问,denied表示不能访问,prompt表示浏览器在请求权限的时候弹出提示,询问用户。 有些 PermissionDescriptor 还有其他字段,你可以在这里查看更多。例如,camera的PermissionDescriptor还有一个额外的字段叫deviceId,用于指定某个摄像头。查询可能是这样:.query({name: 'camera', deviceId: "my-device-id"})。 onchange 是个事件监听器,当查询的权限变化时会被触发。 navigator.permissions.query({name:'camera'}).then(res => { res.onchange = ((e)=>{ if (e.type === 'change'){ const newState = e.target.state if (newState === 'denied') { console.log('你怎么狠心拒绝我?') } else if (newState === 'granted') { console.log('在一起,不离不弃!') } else { console.log('让我们回到当初') } } }) }) 所有的权限 API 强力特性权限还有很多,并且浏览器支持情况不一。下面列出了W3C 编辑草案中描述的 permissionsName 变量包含的所有权限。getAllPermissions函数返回可用的权限数组及其状态。注意,这个结果会根据你的浏览器、用户设置和网站的设定而变化。 const permissionsNames = [ "geolocation", "notifications", "push", "midi", "camera", "microphone", "speaker", "device-info", "background-fetch", "background-sync", "bluetooth", "persistent-storage", "ambient-light-sensor", "accelerometer", "gyroscope", "magnetometer", "clipboard", "display-capture", "nfc" ]; const getAllPermissions = async () => { const allPermissions = []; await Promise.all( permissionsNames.map(async permissionName => { try { let permission; switch (permissionName) { case 'push': // 目前 Chrome 只支持用通知推送消息 permission = await navigator.permissions.query({name: permissionName, userVisibleOnly: true}); break; default: permission = await navigator.permissions.query({name: permissionName}); } console.log(permission); allPermissions.push({permissionName, state: permission.state}); } catch(e){ allPermissions.push({permissionName, state: 'error', errorMessage: e.toString()}); } }) ) return allPermissions; } 在浏览器控制台执行: (async function () { const allPermissions = await getAllPermissions(); console.log(allPermissions); })() 结果如下: image.png Worker 中的权限 到目前为止,我们只使用了 navigator.permissions API,因为用它写的例子更简单明了。权限 API 在 Worker 里同样可用,WorkerNavigator.permissions 即用于检查 Worker 内部的权限。 总结 本文简单介绍了 JavaScript 权限 API,希望能帮助你了解它的基本用法。它不复杂,也不是必需的,但如果你的网站要用到权限接口,用它来管理还是比较方便的。API 以后可能会有所变化,我会为你持续关注。 更多前端技术干货尽在微信公众号:1024译站 微信公众号:1024译站

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):