Bản dùng thử theo nguyên gốc cho phần tử HTML <permission> mới

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 các ứng dụng web. Các phương thức này gặp phải một số thách thức, đó là lý do nhóm quản lý quyền của Chrome đang thử nghiệm một phương thức khai báo mới: phần tử HTML <permission> chuyên dụng. Phần tử này đang trong giai đoạn dùng thử theo nguyên gốc của Chrome 126 và sau cùng, chúng tôi hy vọng có thể chuẩn hoá phần tử này.

Các phương thức bắt buộc để yêu cầu quyền

Khi cần có quyền truy cập vào các tính năng mạnh mẽ, các ứng dụng web sẽ phải yêu cầu cấp quyền. Ví dụ: khi Google Maps yêu cầu thông tin vị trí của người dùng bằng API vị trí địa lý, các trình duyệt sẽ nhắc người dùng, thường kèm theo tuỳ chọn lưu trữ quyết định đó. Đây là khái niệm được định nghĩa rõ ràng trong thông số kỹ thuật về Quyền.

Yêu cầu ngầm trong lần sử dụng đầu tiên thay vì yêu cầu rõ ràng từ trước

API vị trí địa lý là một API mạnh mẽ và dựa trên cơ chế yêu cầu ngầm dựa trên phương pháp sử dụng đầu tiên. 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 bật lên trong lệnh gọi đầu tiên. Một ví dụ khác là navigator.mediaDevices.getUserMedia().

Các API khác, như API Thông báo hoặc API Chuyển động và Hướng thiết bị, 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 liên quan đến các phương pháp bắt buộc để xin phép

Nội dung 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ẽ bật lê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à nội dung rác về quyền và ảnh hưởng đến cả hai phương pháp, ngầm yêu cầu trong lần sử dụng đầu tiên cũng như yêu cầu rõ ràng ngay từ đầu.

Nhắc nhở cấp quyền truy cập vào micrô hiển thị khi đang tải một trang web.

Yêu cầu về cử chỉ của người dùng và các biện pháp giảm thiểu tác động của trình duyệt

Hành vi vi phạm quyền đã khiến các nhà cung cấp trình duyệt yêu cầu người dùng phải thực hiện một cử chỉ như nhấp vào nút hoặc sự kiện nhấn phím trước khi hiển thị lời nhắc cấp quyền. Vấn đề của phương pháp này là rất khó (nếu không muốn nói là) để trình duyệt tìm hiểu xem liệu một cử chỉ cụ thể của người dùng có dẫn đến 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 một cách khó chịu ở bất cứ đâu vì trang tải quá lâu hoặc có thể họ thực sự đang nhấp vào nút Find me (Tìm 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 tuỳ chọn giảm thiểu hành vi sai trái liên quan đến lời nhắc, chẳng hạn như bắt đầu bằng các tính năng chặn hoàn toàn hoặc hiển thị lời nhắc cấp quyền theo cách thức không theo phương thức và ít xâm phạm hơn.

Trình duyệt Chrome đang hiển thị

Hiện bối cảnh của 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 thường hiển thị lời nhắc cấp quyền: phía trên đường chết, 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. Chắc hẳn người dùng sẽ bỏ lỡ lời nhắc ở đầu cửa sổ trình duyệt khi họ chỉ 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 trên trình duyệt được áp dụng.

Google Maps với lời nhắc cấp quyền truy cập thông tin vị trí đang mở. Nút truy cập thông tin vị trí đã kích hoạt lời nhắc ở cách xa.

Không dễ dàng huỷ

Cuối cùng, người dùng quá dễ dàng tự chuyển mình vào đườ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ọ phải biết thông tin trang web trong trình đơn thả xuống 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 tuỳ 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ập nhật có hiệu lực. Các trang web không thể cung cấp lối tắt dễ dàng để người dùng thay đổi trạng thái cấp quyền hiện có, đồng thời phải giải thích tỉ mỉ cho người dùng cách thay đổi chế độ cài đặt như minh hoạ ở cuối ảnh chụp màn hình sau đây của Google Maps.

Kiểm soát trang web Chrome trên Google Maps để thu hồi quyền.

Nếu quyền là yếu tố quan trọng đối với trải nghiệm của bạn, chẳng hạn như quyền truy cập vào micrô của 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 đó.

Hướng dẫn về Google Meet về cách mở các chế độ điều khiển trang web trên Chrome.

Phần tử <permission> mang tính khai báo

Để giải quyết các thách thức được mô tả trong bài đăng này, nhóm phụ trách quyền của Chrome đã phát hành bản dùng thử theo nguyên gốc cho một phần tử HTML mới là <permission>. Phần tử này cho phép các nhà phát triển tuyên bố yêu cầu quyền sử dụng, hiện tại, đây là một tập hợp con gồm các tính năng mạnh mẽ dành cho trang web. Ở dạng đơn giản nhất, bạn sử dụng như trong ví dụ sau:

<permission type="camera" />

Vấn đề này vẫn đang được tích cực tranh luận xem <permission> có nên là một phần tử trống hay không. Phần tử khoảng trố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 có nghĩa là phần tử này 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 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'camera microphone (được 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 barebones.

Nhiều nút trong phần tử quyền có quyền truy cập vào máy ảnh, micrô, máy ảnh và micrô.

Thuộc tính type-ext

Đối với một số quyền cho phép bổ sung tham 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 đối với quyền truy cập thông tin vị trí địa lý.

Thuộc tính lang

Văn bản nút do trình duyệt cung cấp và có mục đích nhất quán, vì vậy, không thể tuỳ chỉnh trực tiếp. Trình duyệt sẽ thay đổi ngôn ngữ của văn bản dựa trên ngôn ngữ kế thừa của tài liệu, chuỗi phần tử mẹ hoặc một thuộc tính lang (không bắt buộc). Tức là nhà phát triển không cần phải tự bản địa hoá phần tử <permission>. Nếu phần tử <permission> tiếp tục vượt quá giai đoạn dùng thử theo nguyên gốc, 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 muốn sử dụng phần tử <permission> cũng như cần một chuỗi hoặc biểu tượng cụ thể, hãy liên hệ!

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 trước đây chưa cho phép một tính năng, thì họ có thể cho phép tính năng đó vào mỗi lượt truy cập hoặc cho phép tính năng đó hiển thị trong lượt truy cập hiện tại.

    Lời nhắc cấp quyền để cho phép một tính năng vào lần này hoặc mỗi lần truy cập.

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

    Lời nhắc cấp quyền để tiếp tục cho phép hoặc dừng cho phép.

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

    Lời nhắc cấp quyền để tiếp tục không cho phép hoặc không cho phép lần này.

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 bạn đã cấp quyền sử dụng một tính năng, thì văn bản sẽ thay đổi thành cho biết tính năng đó được cho phép. Nếu cần được cấp quyền trước, thì 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 để xem 2 trạng thái.

Nút quyền có chứa văn bản

Thiết kế CSS

Để đảm bảo người dùng có thể dễ dàng nhận ra nút là một nền tảng để sử dụng các tính năng hiệu quả, việc định kiểu của phần tử <permission> sẽ bị hạn chế. Nếu các hạn chế về tạo kiểu không phù hợp với trường hợp sử dụng của bạn, chúng tôi muốn biết cách thực hiện và lý do tại sao! Mặc dù không phải nhu cầu tạo kiểu nào cũng đáp ứng được, nhưng chúng tôi hy vọng tìm được những cách an toàn để cho phép tạo kiểu nhiều hơn cho phần tử <permission> sau thời gian dùng thử theo nguyên gốc. Bảng sau đây trình bày chi tiết về một số thuộc tính có áp dụng các quy tắc hạn chế hoặc quy tắc đặc biệt. Trong trường hợp vi phạm bất kỳ quy tắc nào, phần tử <permission> sẽ bị tắt và không thể tương tác. Mọi nỗ lực tương tác với đoạn mã này đều sẽ dẫn đến các trường hợp ngoại lệ có thể phát hiện được bằng JavaScript. Thông báo lỗi sẽ chứa nhiều thông tin chi tiết hơn về lỗi vi phạm đã phát hiện.

Thuộc tính Quy tắc

color, background-color

Có thể được sử dụng để đặt văn bản và màu nền tương ứng. Độ tương phản giữa 2 màu phải đủ để văn bản rõ ràng dễ đọc (tỷ lệ tương phản ít nhất là 3). Kênh alpha phải là 1.

font-size, zoom

Giá trị này phải được đặt trong giá trị tương đương với smallxxxlarge. Nếu không, thành phần này sẽ bị tắt. Thu phóng sẽ được tính đến khi tính toán font-size.

outline-offset

Giá trị âm sẽ được sửa thành 0.
margin (tất cả) Giá trị âm sẽ được sửa thành 0.

font-weight

Các giá trị dưới 200 sẽ được sửa thành 200.

font-style

Các giá trị không phải là normalitalic sẽ được sửa thành normal.

word-spacing

Các giá trị vượt quá 0.5em sẽ được sửa thành 0.5em. Các giá trị dưới 0 sẽ được sửa thành 0.

display

Các giá trị khác inline-blocknone sẽ được sửa thành inline-block.

letter-spacing

Các giá trị vượt quá 0.2em sẽ được sửa thành 0.2em. Các giá trị dưới -0.05em sẽ được sửa thành -0.05em.

min-height

Sẽ có giá trị mặc định là 1em. Nếu được cung cấp, giá trị được tính toán tối đa giữa giá trị mặc định và giá trị đã cung cấp sẽ được xem xét.

max-height

Sẽ có giá trị mặc định là 3em. Nếu được cung cấp, giá trị được tính toán tối thiểu giữa giá trị mặc định và giá trị đã cung cấp sẽ được xem xét.

min-width

Sẽ có giá trị mặc định là fit-content. Nếu được cung cấp, giá trị tính toán tối đa giữa giá trị mặc định và giá trị đã cung cấp sẽ được xem xét.

max-width

Sẽ có giá trị mặc định là 3 lần fit-content. Nếu được cung cấp, giá trị tính toán tối thiểu giữa giá trị mặc định và giá trị đã cung cấp sẽ được xem xét.

padding-top

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ị trên 1em sẽ được hiệu chỉnh thành 1empadding-bottom sẽ được thiết lập thành giá trị padding-top.

padding-left

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ị vượt quá 5em sẽ được điều chỉnh thành 5empadding-right sẽ được thiết lập thành giá trị padding-left.

transform

Những hiệu ứng hình ảnh bị méo sẽ không được phép. Hiện tại, chúng tôi chỉ chấp nhận bản dịch 2D và việc điều chỉnh theo tỷ lệ theo tỷ lệ.

Bạn có thể sử dụng các thuộc tính CSS sau như bình thường:

  • 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 (và tất cả tài sản 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-* (ngoại trừ được lưu ý trước đó cho 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

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), tuân theo các quy tắc tương đương.

Lớp giả

Có 2 lớp giả đặc biệt cho phép định kiểu phần tử <permission> dựa trên trạng thái:

  • :granted: Lớp giả :granted cho phép tạo kiểu đặc biệt khi được cấp quyền.
  • :invalid: Lớp giả :invalid cho 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 gốc.
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 API Quyền. Có một số sự kiện mà bạn có thể nghe:

  • onpromptdismiss: Sự kiện này được kích hoạt khi người dùng đã đóng lời nhắc cấp 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 giải quyết bằng cách người dùng tự thực hiện một số thao tác đối với 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, mà có thể người dùng đã thực hiện một hành động để duy trì hiện trạng (chẳng hạn như tiếp tục cấp quyền).

  • onvalidationstatuschange: Sự kiện này được kích hoạt khi phần tử chuyển từ "valid" sang "invalid". Phần tử này đượ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" nếu không thì khi phần tử bị nội dung HTML khác che khuất một phần.

Bạn có thể đăng ký trình nghe sự kiện cho những sự kiện này trực tiếp cùng dòng trong mã HTML (<permission type="…" onpromptdismiss="alert('The prompt was dismissed');" />) hoặc sử dụng addEventListener() trên phần tử <permission>, như 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 tính năng

Nếu trình duyệt không hỗ trợ phần tử HTML, 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 biết phần tử đó. Có thể bạn vẫn muốn phát hiện sự hỗ trợ bằng cách sử dụng JavaScript, chẳng hạn như để tạo lời nhắc cấp quyền được kích hoạt thông qua một lần 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

Để dùng thử phần tử <permission> trên trang web của bạn với người dùng thực, hãy đăng ký bản dùng thử theo nguyên gốc. Hãy đọc bài viết Bắt đầu sử dụng bản dùng thử theo nguyên gốc để biết hướng dẫn về cách chuẩn bị trang web của bạn để sử dụng bản dùng thử theo nguyê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. Dưới đây là ảnh chụp màn hình trải nghiệm trên một trình duyệt được hỗ trợ.

Bản minh hoạ phần tử quyền cho thấy 3 nút cấp quyền.

Ý kiến phản hồi

Chúng tôi muốn biết ý kiến của bạn về cách hoạt động của <permission> trong trường hợp sử dụng của bạn. Bạn có thể thoải mái 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 kho lưu trữ 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ử đó.

Câu hỏi thường gặp

  • Tính năng này tốt hơn <button> thông thường được ghép nối với API Quyền như thế nào? Lượt 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 nó được kết nối với yêu cầu xin cấp quyền. Nếu người dùng đã nhấp vào một <permission>, trình duyệt có thể chắc chắn rằng lượt nhấp đó có liên quan đến 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ẽ có nhiều rủi ro hơn. Ví dụ: cho phép người dùng dễ dàng huỷ việc chặn một quyền.
  • Nếu các trình duyệt khác không hỗ trợ phần tử <permission> thì sao? Bạn có thể sử dụng phần tử <permission> làm 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 vào một <button> thông thường. Nhóm quản lý quyền cũng đang phát triển một đoạn mã polyfill. Gắn dấu sao kho lưu trữ GitHub để được thông báo khi kho lưu trữ này đã sẵn sàng.
  • Vấn đề này có được thảo luận với 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ú phiên công khai. Nhóm Chrome cũng đã yêu cầu Vị trí tiêu chuẩn chính thức từ cả hai nhà cung cấp, 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ó nên là một phần tử trống không? Vấn đề này vẫn đang được tích cực tranh luận xem <permission> có nên là một phần tử trống hay không. Nếu bạn muốn gửi ý kiến phản hồi, hãy chia sẻ về Vấn đề đó.

Xác nhận

Tài liệu này do Balázs Engedy, Thomas Nguyen, Penelope McLachlan, Marian Harbach, David WarrenRachel Andrew xem xét.