開発者ドキュメント

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と呼ばれる引数としてオブジェクトを取ります。 権限記述子には、という1つのフィールドがあります name、これはアクセスする権限の名前です。

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

クエリは、に解決されるpromiseを返します PermissionStatus. PermissionStatusには2つのフィールドがあります。 stateonchange.

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 変数。 The 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にはおそらくいくつかの新機能と変更があり、最新情報をお届けします。

モバイルバージョンを終了