Chrome 126 於近期釋出了穩定版本,其中一個比較有意思的更新是給 HTML 帶來一個新的元素:
<permission>
,它將從這個版本開始試用,並且正在努力走向標準化。
今天我們一起來看下這個
<permission>
元素的用法。
Web 許可權提示的問題
當 Web 應用程式需要存取瀏覽器的高級功能時,需要向使用者主動請求授權。例如,當百度地圖使用
Geolocation API
獲取使用者的地理位置時,瀏覽器會提示使用者申請許可權,這是許可權規範中定義明確的概念。
申請許可權的觸發方式一般分為兩類,被動隱式觸發,或者主動顯示觸發:
例如,
Geolocation API
是一個強大的
API
,它的使用依賴於首次使用時隱式詢問的方法。例如,當程式呼叫
navigator.geolocation.getCurrentPosition()
方法時,許可權提示框會在第一次呼叫時自動彈出,還有另外一個例子是
navigator.mediaDevices.getUserMedia()
。
一些其他的
API
,如
Notification API
或
Device Orientation API
,通常有一種顯式的方式透過靜態方法來請求許可權,如
Notification.requestPermission()
或
DeviceMotionEvent.requestPermission()
。
網站可以在載入時立即呼叫諸如
navigator.mediaDevices.getUserMedia()
或
Notification.requestPermission()
等方法。這會導致在使用者還沒與網站進行互動時就彈出許可權提示。這就是明顯的許可權濫用行為,並且影響到兩種方式,既包括首次使用時的隱含詢問,也包括提前明確請求。
許可權濫用導致瀏覽器廠商要求有像點選按鈕或按下按鍵這樣的使用者操作,然後才會顯示許可權提示。這種方法的問題在於,瀏覽器很難確定某個特定的使用者操作是否應該導致顯示許可權提示。也許使用者只是因為頁面載入時間太長而在頁面上隨意某個地方隨便點選,有些網站也變得非常擅長誘騙使用者點選內容來觸發提示。
另一個問題是許可權提示框通常顯示的方式:在網站的 「死亡線」 之上(特別是在大螢幕上),也就是說,在應用程式能夠繪制到的瀏覽器視窗區域之外。使用者在剛剛點選了視窗底部的一個按鈕後,可能會錯過瀏覽器視窗頂部的提示,這種情況還是挺常見的。當瀏覽器有應對許可權濫用的緩解措施時,這個問題往往會更加嚴重。
另外,使用者一旦做出了拒絕某個許可權的操作,之後想要改變就不太容易了。他們得找到特定的地方,比如那個網站資訊下拉選單,然後去進行重設或調整許可權的操作,而且還得重新載入頁面才行。網站也沒辦法提供很方便的途徑讓使用者快速改變許可權狀態,還得詳細地告訴使用者怎麽去找到地方改變設定。
如果某個許可權是非常重要的,比如視訊會議軟體要用麥克風許可權,那像谷歌會議這類的軟體就會彈出很顯眼的對話方塊來告訴使用者怎麽去把之前阻止的許可權給開通。
<permission>
元素
為了解決上面的這些問題,
<permission>
元素誕生了。這個元素允許開發者以聲明方式請求使用許可權,如下例所示:
<permissiontype="camera" />
「type」 內容代表你正在請求的許可權列表(如果有多個可以以空格分割)。目前,允許的值是
'camera'
,
'microphone'
以及
'camera microphone'
。預設情況下,這個元素呈現出來的樣子類別似於具有最簡使用者代理樣式的按鈕。
對於某些允許附加參數的許可權,
type-ext
內容接受以空格分隔的鍵值對,例如
precise:true
地理位置許可權。
當使用者與
<permission>
元素互動時,他們可以迴圈經歷各個階段:
如果他們之前不允許某項功能,他們可以在每次存取時允許該功能,或者在當前存取時允許該功能。
如果他們之前允許該功能,他們可以繼續允許,或者停止允許。
如果他們之前不允許某項功能,他們可以繼續不允許它,或者這次允許它。
<permission>
元素的文本會根據狀態自動更新。例如,如果已授予使用某項功能的許可權,則文本會更改為表示允許使用該功能。如果需要先授予許可權,則文本會更改為邀請使用者使用該功能。將之前的螢幕截圖與以下螢幕截圖進行比較,以檢視這兩種狀態。
<permission>
元素可以與
Permissions API
一起使用。有許多事件可供監聽:
onpromptdismiss
:當元素觸發的許可權提示被使用者關閉(例如,單擊關閉按鈕或單擊提示之外)時,會觸發此事件。
onpromptaction
:當元素觸發的許可權提示已被使用者對提示本身采取某種操作解決時,觸發此事件。這並不一定意味著許可權狀態已經改變,使用者可能已經采取了維持現狀的操作(例如繼續允許許可權)。
onvalidationstatuschange
:當元素從
"valid"
切換到
"invalid"
時觸發此事件,例如當元素被其他超文件標示語言內容部份遮擋時,會認為是
"invalid"
。
我們可以直接在 HTML 程式碼中行內註冊這些事件的事件監聽器(
<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />
),或者在
<permission>
元素上使用
addEventListener()
:
<permissiontype="camera" />
<script>
const permission = document.querySelector('permission');
permission.addEventListener('promptdismiss', showCameraWarning);
functionshowCameraWarning() {
// Show warning that the app isn't fully usable
// unless the camera permission is granted.
}
const permissionStatus = await navigator.permissions.query({name: "camera"});
permissionStatus.addEventListener('change', () => {
// Run the check when the status changes.
if (permissionStatus.state === "granted") {
useCamera();
}
// Run the initial check.
if (permissionStatus.state === "granted") {
useCamera();
}
});</script>
最後
參考:https://developer.chrome.com/blog/permission-element-origin-trial
👇🏻 點選下方閱讀原文,獲取魚皮往期編程幹貨。
往期推薦