使用 Permissions API

本文件提供了一個使用 Permissions API 的基礎指南,該 API 提供了一種以程式設計方式查詢當前上下文的 API 許可權狀態的方法。

請求許可權的麻煩……

Web 上的許可權是必要的惡,但作為開發者處理起來並不有趣。

歷史上,不同的 API 以不一致的方式處理其自身的許可權——例如,Notifications API 有自己檢查許可權狀態和請求許可權的方法,而 Geolocation API 則沒有。

Permissions API 為開發者提供了一種一致的方法,並允許他們在許可權方面實現更好的使用者體驗。具體來說,開發者可以使用 Permissions.query() 來檢查當前上下文中是否已授予、拒絕或需要透過提示來授予使用特定 API 的許可權。在主執行緒中查詢許可權 廣泛支援,在 Worker 中也支援(有一個例外)。

許多 API 現在支援許可權查詢,例如 Clipboard APINotifications APIPush APIWeb MIDI API。在 API 概述 中提供了許多支援許可權的 API 的列表,您可以在 此處相容性表 中瞭解瀏覽器支援情況。

Permissions 還有其他方法可以專門請求使用 API 的許可權以及撤銷許可權,但這些方法已棄用(非標準,和/或不支援)。

一個簡單的例子

對於本文件,我們構建了一個名為 Location Finder 的簡單演示。它使用 Geolocation 來查詢使用者的當前位置並將其顯示在 Google 地圖上。

Screenshot showing a map of Greenfield, UK.

您可以 線上執行示例,或 在 GitHub 上檢視原始碼。大部分程式碼都很簡單且普通——下面我們只介紹與 Permissions API 相關的程式碼,如果您想研究其他部分,請自行檢視程式碼。

訪問 Permissions API

瀏覽器已新增 Navigator.permissions 屬性以允許訪問全域性 Permissions 物件。該物件最終將包含查詢、請求和撤銷許可權的方法,儘管目前它只包含 Permissions.query();請參見下文。

查詢許可權狀態

在我們的示例中,Permissions 功能由一個函式——handlePermission()——處理。該函式首先使用 Permissions.query() 查詢許可權狀態。根據 promise 解析時返回的 PermissionStatus 物件的 state 屬性的值,它會做出不同的響應。

"granted"

“Enable Geolocation”按鈕被隱藏,因為如果 Geolocation 已啟用則不需要它。

"prompt"

“Enable Geolocation”按鈕被隱藏,因為如果使用者將被提示授予 Geolocation 許可權,則不需要它。然後執行 Geolocation.getCurrentPosition() 函式,該函式會提示使用者授予許可權;如果授予許可權(顯示地圖),則執行 revealPosition() 函式,或者如果拒絕許可權(顯示“Enable Geolocation”按鈕),則執行 positionDenied() 函式。

"denied"

“Enable Geolocation”按鈕被顯示(此程式碼也必須在此處,以防頁面首次載入時該原點的許可權狀態已設定為 denied)。

js
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 還應包含一個布林值,指定 userVisibleOnlytrue 還是 false

響應許可權狀態更改

您會注意到我們在上面的程式碼中正在監聽附加到 PermissionStatus 物件上的 change 事件——這允許我們響應我們感興趣的 API 的許可權狀態的任何更改。目前我們只是報告狀態的變化。