有許多必要方法可要求使用位置存取權等強大功能的權限,以便在網路應用程式中使用。這些方法存在許多挑戰,因此 Chrome 權限團隊正在嘗試使用新的宣告式方法:專屬的 HTML <permission>
元素。這個元素在 Chrome 126 的來源試用計畫中,我們最終希望將其標準化。
要求權限的命令式方法
如果網頁應用程式需要存取強大功能,就必須要求授權。舉例來說,當 Google 地圖使用 Geolocation 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-kerning
font-optical-sizing
font-stretch
font-synthesis-weight
font-synthesis-style
font-synthesis-small-caps
font-feature-settings
forced-color-adjust
text-rendering
align-self
anchor-name aspect-ratio
border
(和所有border-*
屬性)clear
color-scheme
contain
contain-intrinsic-width
contain-intrinsic-height
container-name
container-type
counter-*
flex-*
float
height
isolation
justify-self
left
order
orphans
outline-*
(例外狀況:outline-offset
先前例外)overflow-anchor
overscroll-behavior-*
page
position
position-anchor
content-visibility
right
scroll-margin-*
scroll-padding-*
text-spacing-trim
top
visibility
x
y
ruby-position
user-select
width
will-change
z-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>
元素的 repo 中的公開信號會讓我們和其他瀏覽器知道您對此感興趣。
常見問題
- 與搭配 Permissions API 的一般
<button>
相比,這有何優勢?點按<button>
是使用者動作,但瀏覽器無法驗證該動作是否與要求權限的請求相關。如果使用者點選<permission>
,瀏覽器就可以確保點擊與權限要求相關。這樣一來,瀏覽器就能促進原本風險較高的流程。例如,允許使用者輕鬆撤銷對權限的封鎖。 - 如果其他瀏覽器不支援
<permission>
元素,該怎麼辦?<permission>
元素可用於漸進式增強功能。在未支援的瀏覽器上,您可以使用傳統權限流程。例如,根據一般<button>
的點擊次數。權限團隊也正在處理 polyfill。為 GitHub 存放區按讚,即可在可使用時收到通知。 - 是否與其他瀏覽器供應商討論過這個問題?
<permission>
元素在 2023 年的 W3C TPAC 中,曾在分組會議中積極討論。您可以閱讀公開工作階段附註。Chrome 團隊也要求兩家供應商提供正式的標準立場,請參閱「相關連結」一節。<permission>
元素是與其他瀏覽器持續進行的討論主題,希望將這項元素標準化。 - 這是否應為空元素?是否應將
<permission>
設為空元素,目前仍在積極討論中。如有任何意見,請在問題中提出。
相關連結
特別銘謝
本文件由 Balázs Engedy、Thomas Nguyen、Penelope McLachlan、Marian Harbach、David Warren 和 Rachel Andrew 審查。