Có một số phương thức bắt buộc để yêu cầu quyền sử dụng các tính năng mạnh mẽ như quyền truy cập thông tin vị trí trong ứng dụng web. Những phương thức này đi kèm với một số thách thức, đó là lý do nhóm quyền của Chrome đang thử nghiệm một phương thức khai báo mới: một phần tử <permission> HTML chuyên dụng. Phần tử này đang trong giai đoạn dùng thử theo nguyên gốc từ Chrome 126 và cuối cùng, chúng tôi hy vọng sẽ chuẩn hoá phần tử này.
Phương thức bắt buộc để yêu cầu cấp quyền
Khi cần truy cập vào các tính năng mạnh mẽ, ứng dụng web cần phải yêu cầu cấp quyền. Ví dụ: khi Google Maps yêu cầu vị trí của người dùng bằng Geolocation API, trình duyệt sẽ nhắc người dùng, thường là có lựa chọn lưu trữ quyết định đó. Đây là một khái niệm được xác định rõ ràng trong quy cách Quyền.
Hỏi ngầm khi sử dụng lần đầu so với yêu cầu rõ ràng ngay từ đầu
Geolocation API là một API mạnh mẽ và dựa vào phương pháp ngầm định yêu cầu khi sử dụng lần đầu. Ví dụ: khi một ứng dụng gọi phương thức navigator.geolocation.getCurrentPosition(), lời nhắc cấp quyền sẽ tự động xuất hiện trong lần gọi đầu tiên.
Một ví dụ khác là navigator.mediaDevices.getUserMedia().
Các API khác, chẳng hạn như Notification API hoặc Device Orientation and Motion API, thường có một cách rõ ràng để yêu cầu quyền thông qua một phương thức tĩnh như Notification.requestPermission() hoặc DeviceMotionEvent.requestPermission().
Thách thức với các phương thức bắt buộc để yêu cầu cấp quyền
Thư rác về quyền
Trước đây, các trang web có thể gọi các phương thức như navigator.mediaDevices.getUserMedia() hoặc Notification.requestPermission(), nhưng cũng có thể gọi navigator.geolocation.getCurrentPosition() ngay khi một trang web được tải. Lời nhắc cấp quyền sẽ xuất hiện trước khi người dùng tương tác với trang web. Điều này đôi khi được mô tả là yêu cầu cấp quyền hàng loạt và ảnh hưởng đến cả hai phương pháp, ngầm yêu cầu khi sử dụng lần đầu cũng như yêu cầu rõ ràng ngay từ đầu.

Các biện pháp giảm thiểu của trình duyệt và yêu cầu về cử chỉ của người dùng
Thư rác xin cấp quyền khiến các nhà cung cấp trình duyệt yêu cầu người dùng thực hiện một cử chỉ như nhấp vào nút hoặc sự kiện keydown trước khi hiển thị lời nhắc cấp quyền. Vấn đề với phương pháp này là trình duyệt rất khó (nếu không muốn nói là không thể) xác định xem một cử chỉ nhất định của người dùng có dẫn đến việc lời nhắc cấp quyền xuất hiện hay không. Có thể người dùng chỉ nhấp vào trang ở bất kỳ vị trí nào vì quá thất vọng khi trang mất quá nhiều thời gian để tải, hoặc có thể họ thực sự đang nhấp vào nút Tìm vị trí của tôi. Một số trang web cũng rất giỏi lừa người dùng nhấp vào nội dung để kích hoạt lời nhắc.
Một biện pháp giảm thiểu khác là thêm các biện pháp giảm thiểu hành vi sử dụng câu lệnh sai mục đích, chẳng hạn như chặn hoàn toàn các tính năng ngay từ đầu hoặc hiển thị lời nhắc cấp quyền theo cách không phương thức và ít xâm nhập hơn.

Bối cảnh hoá quyền
Một thách thức khác (đặc biệt là trên màn hình lớn) là cách lời nhắc cấp quyền thường được hiển thị: phía trên đường giới hạn, tức là bên ngoài khu vực cửa sổ trình duyệt mà ứng dụng có thể vẽ lên. Không phải là không có trường hợp người dùng bỏ lỡ lời nhắc ở đầu cửa sổ trình duyệt khi họ vừa nhấp vào một nút ở cuối cửa sổ. Vấn đề này thường trở nên trầm trọng hơn khi các biện pháp giảm thiểu nội dung rác của trình duyệt được áp dụng.

Không dễ hoàn tác
Cuối cùng, người dùng rất dễ tự điều hướng đến một ngõ cụt. Ví dụ: sau khi người dùng chặn quyền truy cập vào một tính năng, họ cần biết đến trình đơn thả xuống thông tin trang web để có thể Đặt lại quyền hoặc bật lại các quyền bị chặn. Trong trường hợp xấu nhất, cả hai lựa chọn đều yêu cầu tải lại toàn bộ trang cho đến khi chế độ cài đặt mới có hiệu lực. Các trang web không có khả năng cung cấp lối tắt dễ dàng để người dùng thay đổi trạng thái quyền hiện có và phải giải thích cặn kẽ cho người dùng cách thay đổi chế độ cài đặt của họ như minh hoạ ở cuối ảnh chụp màn hình Google Maps sau đây.

Nếu quyền này là yếu tố then chốt đối với trải nghiệm, chẳng hạn như quyền truy cập micrô đối với một ứng dụng hội nghị truyền hình, thì các ứng dụng như Google Meet sẽ hiển thị các hộp thoại xâm nhập hướng dẫn người dùng cách bỏ chặn quyền.

Một phần tử <permission> khai báo
Để giải quyết những thách thức được mô tả trong bài đăng này, nhóm quyền của Chrome đã ra mắt một thử nghiệm nguồn gốc cho một phần tử HTML mới, <permission>. Hiện tại, phần tử này cho phép nhà phát triển khai báo yêu cầu cấp quyền sử dụng một tập hợp con các tính năng mạnh mẽ có sẵn cho trang web. Nói một cách đơn giản, bạn có thể dùng nó như trong ví dụ sau:
<permission type="camera" />
Người ta vẫn đang tích cực tranh luận về việc <permission> có nên là một phần tử trống hay không. Phần tử rỗng là một phần tử tự đóng trong HTML, không thể có bất kỳ nút con nào. Trong HTML, điều này có nghĩa là phần tử rỗng có thể không có thẻ đóng.
Thuộc tính type
Thuộc tính type chứa danh sách các quyền được phân tách bằng dấu cách mà bạn đang yêu cầu. Tại thời điểm viết bài này, các giá trị được phép là 'camera', 'microphone' và camera microphone (phân tách bằng dấu cách). Theo mặc định, phần tử này hiển thị tương tự như các nút có kiểu tác nhân người dùng cơ bản.

Thuộc tính type-ext
Đối với một số quyền cho phép dùng thêm các thông số, thuộc tính type-ext chấp nhận các cặp khoá-giá trị được phân tách bằng dấu cách, chẳng hạn như precise:true cho quyền truy cập thông tin vị trí địa lý.
Thuộc tính lang
Văn bản trên nút do trình duyệt cung cấp và phải nhất quán, vì vậy, bạn không thể tuỳ chỉnh trực tiếp văn bản này. Trình duyệt sẽ thay đổi ngôn ngữ của văn bản dựa trên ngôn ngữ được kế thừa của tài liệu hoặc chuỗi phần tử mẹ, hoặc một thuộc tính lang không bắt buộc. Điều này có nghĩa là nhà phát triển không cần tự bản địa hoá phần tử <permission>. Nếu phần tử <permission> vượt quá giai đoạn thử nghiệm ban đầu, thì một số chuỗi hoặc biểu tượng có thể được hỗ trợ cho từng loại quyền để tăng tính linh hoạt. Nếu bạn quan tâm đến việc sử dụng phần tử <permission> và cần một chuỗi hoặc biểu tượng cụ thể, hãy liên hệ với chúng tôi!
Hành vi
Khi tương tác với phần tử <permission>, người dùng có thể chuyển qua nhiều giai đoạn:
Nếu chưa cho phép một tính năng nào đó trước đây, họ có thể cho phép tính năng đó mỗi lần truy cập hoặc cho phép tính năng đó trong lần truy cập hiện tại.

Nếu đã cho phép tính năng này trước đây, họ có thể tiếp tục cho phép hoặc ngừng cho phép.

Nếu trước đây đã không cho phép một tính năng, thì lần này họ có thể tiếp tục không cho phép hoặc cho phép.

Văn bản của phần tử <permission> sẽ tự động cập nhật dựa trên trạng thái. Ví dụ: nếu quyền sử dụng một tính năng được cấp, thì văn bản sẽ thay đổi để cho biết tính năng đó được phép. Nếu cần cấp quyền trước, văn bản sẽ thay đổi để mời người dùng sử dụng tính năng này. So sánh ảnh chụp màn hình trước đó với ảnh chụp màn hình sau đây để xem 2 trạng thái.

Thiết kế CSS
Để đảm bảo người dùng có thể dễ dàng nhận ra nút này là một vị trí để truy cập vào các chức năng mạnh mẽ, bạn không được tuỳ chỉnh kiểu của phần tử <permission>. Nếu các quy định hạn chế về kiểu chữ không phù hợp với trường hợp sử dụng của bạn, chúng tôi rất mong được biết về cách thức và lý do! Mặc dù không thể đáp ứng mọi nhu cầu về kiểu dáng, nhưng chúng tôi hy vọng sẽ tìm ra những cách an toàn để cho phép tạo kiểu cho phần tử <permission> nhiều hơn sau giai đoạn dùng thử ban đầu. Bảng sau đây trình bày chi tiết một số thuộc tính có các quy tắc đặc biệt hoặc hạn chế áp dụng cho chúng. Trong trường hợp có bất kỳ quy tắc nào bị vi phạm, phần tử <permission> sẽ bị vô hiệu hoá và không tương tác được. Mọi nỗ lực tương tác với đối tượng này sẽ dẫn đến các trường hợp ngoại lệ có thể được phát hiện bằng JavaScript. Thông báo lỗi sẽ chứa thêm thông tin chi tiết về lỗi vi phạm được phát hiện.
| Thuộc tính | Quy tắc |
|---|---|
|
Có thể dùng để đặt màu văn bản và màu nền tương ứng. Độ tương phản giữa hai màu phải đủ để văn bản dễ đọc (tỷ lệ tương phản tối thiểu là 3). Kênh alpha phải là 1. |
|
Phải được đặt trong khoảng tương đương với small và xxxlarge. Nếu không, phần tử sẽ bị vô hiệu hoá. Hệ số thu phóng sẽ được tính đến khi tính toán font-size. |
|
Giá trị âm sẽ được điều chỉnh thành 0. |
margin (tất cả) |
Giá trị âm sẽ được điều chỉnh thành 0. |
|
Các giá trị dưới 200 sẽ được điều chỉnh thành 200. |
|
Các giá trị không phải normal và italic sẽ được điều chỉnh thành normal. |
|
Các giá trị lớn hơn 0.5em sẽ được điều chỉnh thành 0.5em. Các giá trị dưới 0 sẽ được điều chỉnh thành 0. |
|
Các giá trị không phải inline-block và none sẽ được điều chỉnh thành inline-block. |
|
Các giá trị lớn hơn 0.2em sẽ được điều chỉnh thành 0.2em. Các giá trị dưới -0.05em sẽ được điều chỉnh thành -0.05em. |
|
Sẽ có giá trị mặc định là 1em. Nếu được cung cấp, giá trị được tính tối đa giữa giá trị mặc định và giá trị được cung cấp sẽ được xem xét. |
|
Sẽ có giá trị mặc định là 3em. Nếu được cung cấp, giá trị tối thiểu được tính toán giữa giá trị mặc định và giá trị được cung cấp sẽ được xem xét. |
|
Sẽ có giá trị mặc định là fit-content. Nếu được cung cấp, giá trị được tính tối đa giữa giá trị mặc định và giá trị được cung cấp sẽ được xem xét. |
|
Sẽ có giá trị mặc định là 3 lần fit-content. Nếu được cung cấp, giá trị tối thiểu được tính toán giữa giá trị mặc định và giá trị được cung cấp sẽ được xem xét. |
|
Chỉ có hiệu lực nếu bạn đặt height thành auto. Trong trường hợp này, các giá trị lớn hơn 1em sẽ được điều chỉnh thành 1em và padding-bottom sẽ được đặt thành giá trị của padding-top. |
|
Chỉ có hiệu lực nếu bạn đặt width thành auto. Trong trường hợp này, các giá trị lớn hơn 5em sẽ được điều chỉnh thành 5em và padding-right sẽ được đặt thành giá trị của padding-left. |
|
Chúng tôi sẽ không cho phép sử dụng hiệu ứng hình ảnh làm biến dạng. Hiện tại, chúng tôi chỉ chấp nhận bản dịch 2D và việc tăng tỷ lệ theo tỷ lệ. |
Bạn có thể sử dụng các thuộc tính CSS sau đây như bình thường:
font-kerningfont-optical-sizingfont-stretchfont-synthesis-weightfont-synthesis-stylefont-synthesis-small-capsfont-feature-settingsforced-color-adjusttext-renderingalign-selfanchor-name aspect-ratioborder(và tất cảborder-*thuộc tính)clearcolor-schemecontaincontain-intrinsic-widthcontain-intrinsic-heightcontainer-namecontainer-typecounter-*flex-*floatheightisolationjustify-selfleftorderorphansoutline-*(ngoại trừoutline-offsetnhư đã lưu ý ở trên)overflow-anchoroverscroll-behavior-*pagepositionposition-anchorcontent-visibilityrightscroll-margin-*scroll-padding-*text-spacing-trimtopvisibilityxyruby-positionuser-selectwidthwill-changez-index
Ngoài ra, bạn có thể sử dụng tất cả các thuộc tính tương đương về mặt logic (ví dụ: inline-size tương đương với width), theo các quy tắc tương tự như thuộc tính tương đương.
Lớp giả
Có 2 giả lớp đặc biệt cho phép tạo kiểu cho phần tử <permission> dựa trên trạng thái:
:granted: Lớp giả:grantedcho phép tạo kiểu đặc biệt khi một quyền được cấp.:invalid: Lớp giả:invalidcho phép tạo kiểu đặc biệt khi phần tử ở trạng thái không hợp lệ, chẳng hạn như khi phần tử được phân phát trong một iframe trên nhiều nguồn.
permission {
background-color: green;
}
permission:granted {
background-color: light-green;
}
/* Not supported during the origin trial. */
permission:invalid {
background-color: gray;
}
Sự kiện JavaScript
Phần tử <permission> được dùng cùng với Permissions API.
Có một số sự kiện mà bạn có thể theo dõi:
onpromptdismiss: Sự kiện này sẽ kích hoạt khi người dùng đóng lời nhắc về quyền do phần tử kích hoạt (ví dụ: bằng cách nhấp vào nút đóng hoặc nhấp vào bên ngoài lời nhắc).onpromptaction: Sự kiện này được kích hoạt khi lời nhắc cấp quyền do phần tử kích hoạt đã được người dùng giải quyết bằng cách thực hiện một số thao tác trên chính lời nhắc đó. Điều này không nhất thiết có nghĩa là trạng thái quyền đã thay đổi, người dùng có thể đã thực hiện một hành động duy trì nguyên trạng (chẳng hạn như tiếp tục cho phép một quyền).onvalidationstatuschange: Sự kiện này sẽ kích hoạt khi phần tử chuyển từ trạng thái"valid"sang"invalid". Phần tử được coi là"valid"khi trình duyệt tin tưởng tính toàn vẹn của tín hiệu nếu người dùng nhấp vào phần tử đó và"invalid"trong trường hợp khác, chẳng hạn như khi phần tử bị che khuất một phần bởi nội dung HTML khác.
Bạn có thể đăng ký trình nghe sự kiện cho các sự kiện này ngay trong mã HTML (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />) hoặc bằng cách sử dụng addEventListener() trên phần tử <permission>, như minh hoạ trong ví dụ sau.
<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>
Phát hiện đối tượng
Nếu một trình duyệt không hỗ trợ một phần tử HTML, thì trình duyệt đó sẽ không hiển thị phần tử đó. Điều này có nghĩa là nếu bạn có phần tử <permission> trong mã HTML, thì sẽ không có gì xảy ra nếu trình duyệt không nhận biết được phần tử đó. Bạn vẫn có thể muốn phát hiện khả năng hỗ trợ bằng JavaScript, chẳng hạn như để tạo lời nhắc về quyền được kích hoạt thông qua một lượt nhấp vào <button> thông thường.
if ('HTMLPermissionElement' in window) {
// The `<permission>` element is supported.
}
Bản dùng thử theo nguyên gốc
Để thử nghiệm phần tử <permission> trên trang web của bạn với người dùng thực, hãy đăng ký dùng thử nguồn gốc.
Hãy đọc bài viết Bắt đầu dùng thử nguồn gốc để biết hướng dẫn về cách chuẩn bị trang web của bạn để sử dụng tính năng dùng thử nguồn gốc. Bản dùng thử theo nguyên gốc sẽ chạy từ Chrome 126 đến 131 (ngày 19 tháng 2 năm 2025).
Bản minh hoạ
Khám phá bản minh hoạ và xem mã nguồn trên GitHub. Đây là ảnh chụp màn hình về trải nghiệm trên một trình duyệt được hỗ trợ.

Phản hồi
Chúng tôi rất mong nhận được ý kiến của bạn về cách <permission> hoạt động trong trường hợp sử dụng của bạn. Bạn có thể tự do phản hồi một trong các Vấn đề trong kho lưu trữ hoặc gửi một vấn đề mới. Các tín hiệu công khai trong repo cho phần tử <permission> sẽ cho chúng tôi và các trình duyệt khác biết rằng bạn quan tâm đến phần tử này.
Câu hỏi thường gặp
- Điều này có gì tốt hơn so với
<button>thông thường kết hợp với Permissions API? Thao tác nhấp vào<button>là một cử chỉ của người dùng, nhưng trình duyệt không có cách nào xác minh rằng thao tác này có liên quan đến yêu cầu cấp quyền. Nếu người dùng đã nhấp vào<permission>, thì trình duyệt có thể chắc chắn rằng lượt nhấp đó có liên quan đến một yêu cầu cấp quyền. Điều này cho phép trình duyệt hỗ trợ các luồng mà nếu không thì sẽ rủi ro hơn nhiều. Ví dụ: cho phép người dùng dễ dàng huỷ chặn một quyền. - Điều gì sẽ xảy ra nếu các trình duyệt khác không hỗ trợ phần tử
<permission>? Bạn có thể dùng phần tử<permission>làm một tính năng nâng cao tăng dần. Trên các trình duyệt không hỗ trợ, bạn có thể sử dụng quy trình cấp quyền kiểu cũ. Ví dụ: dựa trên lượt nhấp của một<button>thông thường. Nhóm quyền cũng đang làm việc trên một polyfill. Gắn dấu sao cho kho lưu trữ GitHub để nhận được thông báo khi tính năng này ra mắt. - Vấn đề này có được thảo luận với các nhà cung cấp trình duyệt khác không? Phần tử
<permission>đã được thảo luận tích cực tại W3C TPAC vào năm 2023 trong một phiên họp nhóm. Bạn có thể đọc ghi chú công khai về buổi đào tạo. Nhóm Chrome cũng đã yêu cầu cả hai nhà cung cấp đưa ra các Tiêu chuẩn chính thức, hãy xem phần Đường liên kết có liên quan. Phần tử<permission>là một chủ đề đang được thảo luận với các trình duyệt khác và chúng tôi hy vọng sẽ chuẩn hoá phần tử này. - Đây có thực sự là một phần tử trống không? Người ta vẫn đang tích cực tranh luận về việc
<permission>có nên là một phần tử trống hay không. Nếu bạn có ý kiến phản hồi, hãy tham gia thảo luận về Vấn đề này.
Đường liên kết có liên quan
Lời cảm ơn
Tài liệu này được xem xét bởi Balázs Engedy, Thomas Nguyen, Penelope McLachlan, Marian Harbach, David Warren và Rachel Andrew.