Chủ Nhật, 05/01/2020 | 00:00 GMT+7

Tham quan API quyền JavaScript


Nếu bạn đã từng tạo một ứng dụng web yêu cầu các tính năng khác nhau (như thông báo đẩy, truy cập webcam, truy cập midi), bạn có thể nhận thấy rằng các API của chúng trông rất khác nhau.

// for the geolocation API you need to call getCurrentPosition to check if geolocation is accessible
navigator.geolocation.getCurrentPosition(gotLocation, didNotGetLocation);

// for notifications we can directly check on the Notification object

if (Notification.permission == 'granted')
  // do notification stuff
if (Notification.permission == 'denied')
  // ask for notification access ....

Điều này không phải là rất tiện dụng.

API Quyền cho phép ta có tổng quan về các quyền có sẵn trên các trang của ta . Ý ta nói về “quyền” là liệu ta có thể truy cập một tính năng cụ thể bằng mã của bạn hay không. Các tính năng yêu cầu quyền truy cập chúng bằng mã được gọi là các tính năng mạnh mẽ. Camera, midi, thông báo, định vị đều là những tính năng mạnh mẽ.

Tất cả các API của tính năng mạnh mẽ có một chút khác biệt. Vì vậy, có thể hơi khó khăn khi tìm ra trạng thái của các quyền của mỗi tính năng. Với API quyền, ta quản lý tất cả các trạng thái của quyền bằng một giao diện duy nhất.

Kiến thức cơ bản về API quyền

API quyền đang rất thử nghiệm ở giai đoạn này và cần được sử dụng cẩn thận. Bạn chỉ nên sử dụng nó nếu nó là nhiệm vụ quan trọng và bạn có thể theo kịp những thay đổi đột phá trong tương lai. Ví dụ: một số trình duyệt được sử dụng để hỗ trợ navigator.permissions.revoke nhưng nó hiện không được dùng nữa.

Tại thời điểm viết bài này, query là thuộc tính duy nhất mà ta có thể truy cập từ giao diện permissions . query nhận một đối tượng làm đối số được gọi là PermissionDescriptor . Bộ mô tả quyền có một trường được gọi là name , là tên của quyền mà bạn muốn truy cập.

// This query will give us information about the permissions attached to the camera
navigator.permissions.query({name: 'camera'})

Truy vấn trả về một lời hứa sẽ phân giải thành PermissionStatus . PermissionStatus có hai lĩnh vực: stateonchange .

navigator.permissions.query({name: 'camera'}).then( permissionStatus => {
  console.log(permissionStatus)
  // in my browser on this page it logs:
  //{
  //   status: "prompt",
  //   onchange: null,
  // }
})

state có thể có 3 trạng thái: "được cấp", "bị từ chối" và "nhắc nhở". "Được cấp" nghĩa là ta có quyền truy cập vào tính năng này. "Bị từ chối" nghĩa là ta sẽ không thể truy cập tính năng này. "Nhắc" nghĩa là Tác nhân user (tức là trình duyệt) sẽ yêu cầu user cho phép nếu ta cố gắng truy cập tính năng đó.

Một số PermissionDescriptor có các trường bổ sung và bạn có thể đọc thêm về chúng tại đây . Ví dụ: PermissionDescriptor của camera có một trường bổ sung được gọi là deviceId nếu bạn muốn nhắm đến một máy ảnh cụ thể. Truy vấn của bạn có thể giống như sau: .query({name: 'camera', deviceId: "my-device-id"}) .

onchange là một trình xử lý sự kiện sẽ kích hoạt khi nào các quyền của tính năng được truy vấn thay đổi.

navigator.permissions.query({name:'camera'}).then(res => {
  res.onchange = ((e)=>{
    // detecting if the event is a change
    if (e.type === 'change'){
      // checking what the new permissionStatus state is
      const newState = e.target.state
      if (newState === 'denied') {
        console.log('why did you decide to block us?')
      } else if (newState === 'granted') {
        console.log('We will be together forever!')
      } else {
        console.log('Thanks for reverting things back to normal')
      }
    }
  })
})

API tất cả quyền

Có rất nhiều quyền mạnh mẽ khác nhau và hỗ trợ trình duyệt rất không đồng đều. Trong tập lệnh sau, bạn có thể xem tất cả các quyền được mô tả bởi bản nháp của trình soạn thảo W3C trong biến permissionsName . Hàm getAllPermissions trả về một mảng với các quyền khác nhau có sẵn và trạng thái của chúng. Xin lưu ý kết quả sẽ thay đổi tùy thuộc vào trình duyệt của bạn, sở thích của user và tất nhiên là cài đặt của trang web.

const permissionsNames = [
  "geolocation",
  "notifications",
  "push",
  "midi",
  "camera",
  "microphone",
  "speaker",
  "device-info",
  "background-fetch",
  "background-sync",
  "bluetooth",
  "persistent-storage",
  "ambient-light-sensor",
  "accelerometer",
  "gyroscope",
  "magnetometer",
  "clipboard",
  "display-capture",
  "nfc"
]

const getAllPermissions = async () => {
  const allPermissions = []
  // We use Promise.all to wait until all the permission queries are resolved
  await Promise.all(
    permissionsNames.map(async permissionName => {
        try {
          let permission
          switch (permissionName) {
            case 'push':
              // Not necessary but right now Chrome only supports push messages with  notifications
              permission = await navigator.permissions.query({name: permissionName, userVisibleOnly: true})
              break
            default:
              permission = await navigator.permissions.query({name: permissionName})
          }
          console.log(permission)
          allPermissions.push({permissionName, state: permission.state})
        }
        catch(e){
          allPermissions.push({permissionName, state: 'error', errorMessage: e.toString()})
        }
    })
  )
  return allPermissions
}

Nếu sau đó tôi chạy mã sau trong console dành cho nhà phát triển của bạn trên Alligator.io:

(async function () {
  const allPermissions = await getAllPermissions()
  console.log(allPermissions)
})()

Đây là ảnh chụp màn hình của những gì tôi nhận được tại console :

Quyền đối với Người lao động

Lúc này, ta chỉ sử dụng hàm navigator.permissions API vì việc viết các ví dụ ngắn gọn dễ dàng hơn nhiều. API Quyền cũng có sẵn bên trong worker. WorkerNavigator.permissions cho phép ta kiểm tra các quyền bên trong công nhân của ta .

Hy vọng rằng bây giờ bạn có ý tưởng tốt hơn về cách sử dụng API Quyền. Nó không quá phức tạp, cũng không cần thiết nhưng nó giúp ta quản lý các quyền trong các ứng dụng dựa trên JavaScript của bạn dễ dàng hơn nhiều. Có thể sẽ có một số tính năng và thay đổi mới đối với API và ta sẽ cập nhật cho bạn!


Tags:

Các tin liên quan

V8 của V8: Chuỗi liên kết tùy chọn và kết hợp Nullish trong JavaScript
2019-12-29
Phân tích cú pháp, xác thực, thao tác và hiển thị ngày và giờ trong JavaScript với Day.js
2019-12-28
Cách bắt đầu với API hiệu suất JavaScript
2019-12-25
Xem xét tất cả 13 bẫy proxy JavaScript
2019-12-19
Khám phá phương thức indexOf cho chuỗi và mảng trong JavaScript
2019-12-17
Thao tác DOM trong JavaScript với innerText và innerHTML
2019-12-14
Cách gói một gói JavaScript Vanilla để sử dụng trong React
2019-12-12
Cách phát triển một trình tải lên tệp tương tác với JavaScript và Canvas
2019-12-12
Cách sử dụng map (), filter () và Reduce () trong JavaScript
2019-12-12
Giải thích về lập trình chức năng JavaScript: Ứng dụng một phần và làm xoăn
2019-12-12