在網頁應用程式中,要求使用位置存取權等強大功能的權限時,有許多必要方法。這些方法會帶來許多挑戰,因此 Chrome 權限團隊正在實驗新的宣告式方法:專用的 HTML <permission> 元素。這項元素已在 Chrome 126 進入來源試用階段,我們最終希望將其標準化。
要求權限的命令式方法
網頁應用程式需要存取強大功能時,必須要求授權。舉例來說,當 Google 地圖需要使用地理位置 API 取得使用者位置時,瀏覽器會提示使用者,並提供儲存這項決定的選項。這是權限規格中定義明確的概念。
在首次使用時隱含要求,而非預先明確要求
Geolocation API 是功能強大的 API,採用首次使用時隱含要求的方式。舉例來說,當應用程式呼叫 navigator.geolocation.getCurrentPosition() 方法時,系統會在第一次呼叫時自動彈出權限提示。另一個例子是 navigator.mediaDevices.getUserMedia()。
其他 API (例如 Notification API 或 Device Orientation and Motion API) 通常會透過靜態方法 (例如 Notification.requestPermission() 或 DeviceMotionEvent.requestPermission()) 明確要求權限。
以命令式方法要求權限時遇到的挑戰
權限垃圾內容
過去,網站可以呼叫 navigator.mediaDevices.getUserMedia() 或 Notification.requestPermission() 等方法,但網站載入時也會立即呼叫 navigator.geolocation.getCurrentPosition()。使用者與網站互動前,系統會彈出權限提示。這有時稱為權限垃圾內容,會影響兩種做法:首次使用時隱含要求,以及預先明確要求。

瀏覽器防護措施和使用者手勢規定
由於權限垃圾內容氾濫,瀏覽器供應商要求必須先有使用者手勢 (例如點按按鈕或按下鍵盤事件),才能顯示權限提示。這種做法的問題在於,瀏覽器很難 (甚至無法) 判斷特定使用者手勢是否應顯示權限提示。使用者可能只是因為網頁載入時間過長而感到沮喪,因此隨意點選頁面上的任何位置,也可能確實是點選「尋找我的位置」按鈕。有些網站也很擅長誘騙使用者點選內容,進而觸發提示。
另一項緩解措施是加入提示濫用緩解措施,例如一開始就完全封鎖功能,或是以非強制回應、較不干擾的方式顯示權限提示。

權限情境化
另一個挑戰是權限提示的顯示方式,尤其是在大螢幕上,權限提示通常會顯示在死亡線上方,也就是應用程式可繪製的瀏覽器視窗區域外。使用者點選瀏覽器視窗底部的按鈕時,可能會錯過視窗頂端的提示。如果瀏覽器設有垃圾內容防範措施,這個問題通常會更加嚴重。

無法輕易復原
最後,使用者很容易自行導覽至死胡同。舉例來說,使用者封鎖某項功能的存取權後,必須知道網站資訊下拉式選單的位置,才能重設權限或重新啟用遭封鎖的權限。在最糟的情況下,這兩種選項都需要完整重新載入頁面,更新後的設定才會生效。網站無法提供簡單的捷徑,讓使用者變更現有的權限狀態,因此必須費盡心思向使用者說明如何變更設定,如下方 Google 地圖螢幕截圖底部所示。

如果權限是體驗的關鍵,例如視訊會議應用程式的麥克風存取權,Google Meet 等應用程式會顯示侵入式對話方塊,指示使用者如何解除封鎖權限。

宣告式 <permission> 元素
為解決本文所述的挑戰,Chrome 權限團隊推出了新 HTML 元素 <permission> 的來源試用。開發人員目前可透過這個元素,以宣告方式要求使用網站可用的部分強大功能。最簡單的用法如下列範例所示:
<permission type="camera" />
目前仍在積極討論 <permission> 是否應為空元素。空白元素是 HTML 中的自閉元素,不得有任何子節點,也就是說,在 HTML 中,空白元素可能沒有結束標記。
type 屬性
type 屬性包含以空格分隔的權限清單,列出您要求的權限。撰寫本文時,允許的值為 'camera'、'microphone' 和 camera microphone (以空格分隔)。根據預設,這個元素會以類似按鈕的形式呈現,並採用最基本的使用者代理程式樣式。

type-ext 屬性
對於允許額外參數的某些權限,type-ext 屬性會接受以空格分隔的鍵/值組合,例如地理位置權限的 precise:true。
lang 屬性
按鈕文字由瀏覽器提供,且必須保持一致,因此無法直接自訂。瀏覽器會根據文件或父項元素鏈的繼承語言,或選用的 lang 屬性,變更文字的語言。也就是說,開發人員不需要自行將 <permission> 元素本地化。如果 <permission> 元素通過原始試用階段,每個權限類型可能會支援多個字串或圖示,以提高彈性。如果您有意使用 <permission> 元素,且需要特定字串或圖示,請與我們聯絡!
行為
使用者與 <permission> 元素互動時,可以依序切換至不同階段:
如果使用者先前未允許某項功能,可以選擇每次造訪時允許,或只允許本次造訪。

如果先前已允許使用這項功能,可以繼續允許或停止允許。

如果先前已禁止使用某項功能,可以繼續禁止,也可以這次允許使用。

<permission> 元素的文字會根據狀態自動更新。舉例來說,如果已授予使用某項功能的權限,文字會變更為顯示該功能已獲准使用。如果需要先授予權限,文字會變更為邀請使用者使用這項功能。比較先前的螢幕截圖與下列螢幕截圖,即可查看這兩種狀態。

CSS 設計
為確保使用者能輕鬆辨識按鈕,並將其視為存取強大功能的介面,<permission> 元素的樣式受到限制。如果樣式限制不符合您的使用需求,歡迎告訴我們原因和使用方式!雖然我們無法滿足所有樣式需求,但希望能在原始試用期結束後,找到安全的方法,允許對 <permission> 元素套用更多樣式。下表詳細說明瞭受到限制或適用特殊規則的部分屬性。如有任何規則遭到違反,<permission> 元素就會遭到停用,無法互動。任何與其互動的嘗試都會導致例外狀況,可透過 JavaScript 擷取。錯誤訊息會提供偵測到的違規事項詳細資訊。
| 屬性 | 規則 |
|---|---|
|
可用於分別設定文字和背景顏色。這兩種顏色之間的對比度必須足夠,才能清楚辨識文字 (對比度至少為 3)。Alpha 版必須為 1。 |
|
必須設在 small 和 xxxlarge 的等效值內。否則元素會遭到停用。計算 font-size 時,系統會將縮放比例納入考量。 |
|
負值會修正為 0。 |
margin (全部) |
負值會修正為 0。 |
|
低於 200 的值會修正為 200。 |
|
如果值不是 normal 和 italic,系統會修正為 normal。 |
|
如果值超過 0.5em,系統會修正為 0.5em。低於 0 的值會修正為 0。 |
|
如果值不是 inline-block 和 none,系統會修正為 inline-block。 |
|
如果值超過 0.2em,系統會修正為 0.2em。系統會將低於 -0.05em 的值修正為 -0.05em。 |
|
預設值為 1em。如果提供值,系統會採用預設值和提供值之間的最大計算值。 |
|
預設值為 3em。如果提供值,系統會採用預設值和提供值之間的最小值。 |
|
預設值為 fit-content。如果提供這項屬性,系統會採用預設值和提供值中較大的計算值。 |
|
預設值為 fit-content 的三倍。如果提供值,系統會採用預設值和提供值之間的最小值。 |
|
只有在 height 設為 auto 時才會生效。在這種情況下,系統會將超過 1em 的值修正為 1em,並將 padding-bottom 設為 padding-top 的值。 |
|
只有在 width 設為 auto 時才會生效。在這種情況下,系統會將超過 5em 的值修正為 5em,並將 padding-right 設為 padding-left. 的值。 |
|
不得使用扭曲視覺效果。目前僅接受 2D 翻譯和等比例放大。 |
下列 CSS 屬性可照常使用:
font-kerningfont-optical-sizingfont-stretchfont-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-feature-settingsforced-color-adjusttext-renderingalign-selfanchor-name aspect-ratioborder(和所有border-*屬性)clearcolor-schemecontaincontain-intrinsic-widthcontain-intrinsic-heightcontainer-namecontainer-typecounter-*flex-*floatheightisolationjustify-selfleftorderorphansoutline-*(先前已註明outline-offset的例外狀況)overflow-anchoroverscroll-behavior-*pagepositionposition-anchorcontent-visibilityrightscroll-margin-*scroll-padding-*text-spacing-trimtopvisibilityxyruby-positionuser-selectwidthwill-changez-index
此外,您可以使用所有邏輯上等效的屬性 (例如 inline-size 等於 width),並遵循等效屬性的相同規則。
虛擬類別
有兩個特殊虛擬類別可根據狀態設定 <permission> 元素的樣式:
:granted::granted虛擬類別可在授予權限時套用特殊樣式。:invalid:當元素處於無效狀態時 (例如在跨來源 iframe 中提供服務時),:invalid虛擬類別可提供特殊樣式。
permission {
background-color: green;
}
permission:granted {
background-color: light-green;
}
/* Not supported during the origin trial. */
permission:invalid {
background-color: gray;
}
JavaScript 事件
<permission> 元素應與 Permissions API 一併使用。您可以監聽下列事件:
onpromptdismiss:當使用者關閉元素觸發的權限提示時 (例如點選關閉按鈕或提示以外的區域),系統會觸發這個事件。onpromptaction:當使用者對元素觸發的權限提示採取動作,系統就會觸發這項事件。這不一定表示權限狀態已變更,使用者可能採取了維持現狀的動作 (例如繼續允許權限)。onvalidationstatuschange:當元素從"valid"切換為"invalid"時,系統會觸發這個事件。如果使用者點選元素時,瀏覽器信任信號的完整性,則該元素會視為"valid";否則,該元素會視為"invalid",例如元素部分遭到其他 HTML 內容遮蔽時。
您可以直接在 HTML 程式碼中註冊這些事件的事件監聽器 (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />),也可以使用 <permission> 元素上的 addEventListener(),如下例所示。
<permission type="camera" />
<script>
const permission = document.querySelector('permission');
permission.addEventListener('promptdismiss', showCameraWarning);
function showCameraWarning() {
// 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>
特徵偵測
如果瀏覽器不支援 HTML 元素,就不會顯示該元素。也就是說,如果 HTML 程式碼中有 <permission> 元素,但瀏覽器不認識該元素,就不會發生任何事。您可能仍想使用 JavaScript 偵測支援情形,例如建立透過一般 <button> 點擊觸發的權限提示。
if ('HTMLPermissionElement' in window) {
// The `<permission>` element is supported.
}
來源試用
如要在網站上對實際使用者測試 <permission> 元素,請註冊原始碼試用。如需如何準備網站以使用來源試用計畫的操作說明,請參閱「開始使用來源試用計畫」。來源試用將從 Chrome 126 版開始,到 131 版結束 (2025 年 2 月 19 日)。
示範
瀏覽示範,並查看 GitHub 上的原始碼。以下是支援瀏覽器的體驗螢幕截圖。

意見回饋
我們很樂意瞭解 <permission> 是否符合您的使用需求。歡迎回覆存放區中的問題,或提出新問題。存放區中 <permission> 元素的公開信號會通知我們和其他瀏覽器,您對該元素感興趣。
常見問題
- 與搭配 Permissions API 的一般
<button>相比,這項功能有何優勢?點按<button>是使用者手勢,但瀏覽器無法驗證這是否與要求權限的要求相關。如果使用者點選<permission>,瀏覽器就能確定點擊動作與權限要求有關。這樣一來,瀏覽器就能協助處理原本風險較高的流程。例如,允許使用者輕鬆復原權限封鎖。 - 如果其他瀏覽器不支援
<permission>元素,該怎麼辦?<permission>元素可用於漸進式強化。如果使用不支援的瀏覽器,可以改用傳統權限流程。舉例來說,根據一般<button>的點擊次數。權限團隊也正在開發 Polyfill。為 GitHub 存放區加上星號,以便在準備就緒時收到通知。 - 是否曾與其他瀏覽器供應商討論過這項提案?在 2023 年 W3C TPAC 的分組討論中,
<permission>元素是熱門話題。您可以閱讀公開工作階段附註。Chrome 團隊也已要求這兩家供應商提供正式的標準立場,詳情請參閱「相關連結」一節。<permission>元素是我們與其他瀏覽器持續討論的主題,我們希望將其標準化。 - 這是否應為空元素?
<permission>是否應為空元素,目前仍積極爭論中。如有任何意見,請在問題中提出。
相關連結
特別銘謝
本文由 Balázs Engedy、Thomas Nguyen、Penelope McLachlan、Marian Harbach、David Warren 和 Rachel Andrew 審查。