JavaScriptパーミッションAPIのツアー
さまざまな機能(プッシュ通知、Webカメラアクセス、midiアクセスなど)を必要とするWebアプリケーションを作成したことがある場合は、APIの外観が大きく異なることに気付いたと思います。
// for the geolocation API you need to call getCurrentPosition to check if geolocation is accessible navigator.geolocation.getCurrentPosition(gotLocation, didNotGetLocation); // for notifications we can directly check on the Notification object if (Notification.permission == 'granted') // do notification stuff if (Notification.permission == 'denied') // ask for notification access ....
これはあまり便利ではありません。
パーミッションAPIを使用すると、ページで使用できるパーミッションの概要を把握できます。 「許可」とは、コードを使用して特定の機能にアクセスできるかどうかを意味します。 コードでそれらにアクセスするための許可を必要とする機能は、強力な機能と呼ばれます。 カメラ、midi、通知、ジオロケーションはすべて強力な機能です。
すべての強力な機能のAPIは少し異なります。 したがって、各機能の権限の状態を把握するのは面倒な場合があります。 パーミッションAPIを使用すると、1つのインターフェースですべてのパーミッションのステータスを管理できます。
パーミッションAPIの基本
パーミッションAPIはこの段階では非常に実験的なものであり、慎重に使用する必要があります。 ミッションクリティカルであり、将来の重大な変更に対応できる場合にのみ使用してください。 たとえば、以前はnavigator.permissions.revoke
をサポートしていたブラウザがいくつかありましたが、現在は非推奨になっています。
執筆時点では、query
は、permissions
インターフェイスからアクセスできる唯一のプロパティです。 query
は、PermissionDescriptorと呼ばれる引数としてオブジェクトを取ります。 権限記述子には、name
という1つのフィールドがあります。これは、アクセスする権限の名前です。
// This query will give us information about the permissions attached to the camera navigator.permissions.query({name: 'camera'})
クエリは、PermissionStatus
に解決されるpromiseを返します。 PermissionStatusには、state
とonchange
の2つのフィールドがあります。
navigator.permissions.query({name: 'camera'}).then( permissionStatus => { console.log(permissionStatus) // in my browser on this page it logs: //{ // status: "prompt", // onchange: null, // } })
state
には、「許可」、「拒否」、「プロンプト」の3つの状態があります。 「許可された」とは、その機能にアクセスできることを意味します。 「拒否」とは、その機能にアクセスできないことを意味します。 「プロンプト」とは、ユーザーエージェント(つまり、 ブラウザ)は、その機能にアクセスしようとすると、ユーザーに許可を求めます。
一部のPermissionDescriptor
には追加のフィールドがあり、ここでそれらの詳細を読むことができます。 たとえば、特定のカメラをターゲットにする場合、camera
のPermissionDescriptorにはdeviceId
という追加のフィールドがあります。 クエリは次のようになります:.query({name: 'camera', deviceId: "my-device-id"})
。
onchange
は、照会された機能の権限が変更されるたびにアクティブになるイベントリスナーです。
navigator.permissions.query({name:'camera'}).then(res => { res.onchange = ((e)=>{ // detecting if the event is a change if (e.type === 'change'){ // checking what the new permissionStatus state is const newState = e.target.state if (newState === 'denied') { console.log('why did you decide to block us?') } else if (newState === 'granted') { console.log('We will be together forever!') } else { console.log('Thanks for reverting things back to normal') } } }) })
すべての権限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 = [] // We use Promise.all to wait until all the permission queries are resolved await Promise.all( permissionsNames.map(async permissionName => { try { let permission switch (permissionName) { case 'push': // Not necessary but right now Chrome only supports push messages with notifications 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 }
次に、Alligator.ioの開発者コンソールで次のコードを実行すると次のようになります。
(async function () { const allPermissions = await getAllPermissions() console.log(allPermissions) })()
これが私がコンソールで得たもののスクリーンショットです:
労働者の許可
これまでは、navigator.permissions
APIのみを使用していました。これは、簡潔な例を作成する方がはるかに簡単だからです。 パーミッションAPIは、ワーカー内でも使用できます。 WorkerNavigator.permissions
を使用すると、ワーカー内の権限を確認できます。
うまくいけば、PermissionsAPIの使用方法についてより良いアイデアが得られたと思います。 これはそれほど複雑ではなく、必須でもありませんが、JavaScriptベースのアプリで権限を管理するのがはるかに簡単になります。 APIにはおそらくいくつかの新機能と変更があり、最新情報をお届けします。