Di chuyển sang nội dung gợi ý của ứng dụng tác nhân người dùng

Các chiến lược để di chuyển trang web của bạn từ việc dựa vào chuỗi user-agent sang Thông tin mô tả của ứng dụng tác nhân người dùng mới.

Chuỗi User-Agent là một giao diện vân tay thụ động quan trọng trong trình duyệt, đồng thời khó xử lý. Tuy nhiên, có nhiều lý do hợp lệ để thu thập và xử lý dữ liệu về tác nhân người dùng, vì vậy, bạn cần có một lộ trình để tìm ra giải pháp tốt hơn. Gợi ý ứng dụng của tác nhân người dùng cung cấp cả cách rõ ràng để khai báo nhu cầu của bạn về dữ liệu tác nhân người dùng và các phương thức để trả về dữ liệu ở định dạng dễ sử dụng.

Bài viết này sẽ hướng dẫn bạn cách kiểm tra quyền truy cập vào dữ liệu tác nhân người dùng và chuyển việc sử dụng chuỗi tác nhân người dùng sang Thông tin mô tả của ứng dụng tác nhân người dùng.

Thu thập và sử dụng dữ liệu về tác nhân người dùng trong quy trình kiểm tra

Giống như mọi hình thức thu thập dữ liệu, bạn phải luôn hiểu lý do thu thập dữ liệu. Bước đầu tiên, bất kể bạn có thực hiện hành động nào hay không, là tìm hiểu vị trí và lý do bạn sử dụng dữ liệu về tác nhân người dùng.

Nếu bạn không biết liệu dữ liệu tác nhân người dùng có đang được sử dụng hay không hoặc ở đâu, hãy cân nhắc việc tìm kiếm mã xử lý phía trước để sử dụng navigator.userAgent và mã xử lý phía sau để sử dụng tiêu đề HTTP User-Agent. Bạn cũng nên kiểm tra mã xử lý phía trước để sử dụng các tính năng đã ngừng hoạt động, chẳng hạn như navigator.platformnavigator.appVersion.

Từ quan điểm chức năng, hãy nghĩ đến bất kỳ nơi nào trong mã mà bạn đang ghi lại hoặc xử lý:

  • Tên hoặc phiên bản trình duyệt
  • Tên hoặc phiên bản hệ điều hành
  • Nhà sản xuất hoặc mẫu thiết bị
  • Loại CPU, cấu trúc hoặc số bit (ví dụ: 64 bit)

Cũng có thể bạn đang sử dụng thư viện hoặc dịch vụ của bên thứ ba để xử lý tác nhân người dùng. Trong trường hợp này, hãy kiểm tra xem các ứng dụng đó có đang cập nhật để hỗ trợ Gợi ý cho ứng dụng tác nhân người dùng hay không.

Bạn có đang chỉ sử dụng dữ liệu cơ bản về trình duyệt không?

Tập hợp mặc định của Thông tin mô tả của ứng dụng tác nhân người dùng bao gồm:

  • Sec-CH-UA: tên trình duyệt và phiên bản chính/quan trọng
  • Sec-CH-UA-Mobile: giá trị boolean cho biết thiết bị di động
  • Sec-CH-UA-Platform: tên hệ điều hành
    • Xin lưu ý rằng thông tin này đã được cập nhật trong thông số kỹ thuật và sẽ sớm được phản ánh trong Chrome và các trình duyệt khác dựa trên Chromium.

Phiên bản rút gọn của chuỗi tác nhân người dùng được đề xuất cũng sẽ giữ lại thông tin cơ bản này theo cách tương thích ngược. Ví dụ: thay vì Chrome/90.0.4430.85, chuỗi sẽ bao gồm Chrome/90.0.0.0.

Nếu bạn chỉ kiểm tra chuỗi user-agent để biết tên trình duyệt, phiên bản chính hoặc hệ điều hành, thì mã của bạn sẽ tiếp tục hoạt động mặc dù bạn có thể thấy cảnh báo ngừng sử dụng.

Mặc dù bạn có thể và nên chuyển sang Gợi ý cho ứng dụng tác nhân người dùng, nhưng bạn có thể gặp phải các hạn chế về tài nguyên hoặc mã cũ khiến bạn không thể thực hiện việc này. Việc giảm thông tin trong chuỗi tác nhân người dùng theo cách tương thích ngược này nhằm đảm bảo rằng mặc dù mã hiện có sẽ nhận được ít thông tin chi tiết hơn, nhưng vẫn giữ lại chức năng cơ bản.

Chiến lược: API JavaScript phía máy khách theo yêu cầu

Nếu đang sử dụng navigator.userAgent, bạn nên chuyển sang ưu tiên navigator.userAgentData trước khi quay lại phân tích cú pháp chuỗi user-agent.

if (navigator.userAgentData) {
  // use new hints
} else {
  // fall back to user-agent string parsing
}

Nếu bạn đang kiểm tra thiết bị di động hoặc máy tính, hãy sử dụng giá trị boolean mobile:

const isMobile = navigator.userAgentData.mobile;

userAgentData.brands là một mảng các đối tượng có thuộc tính brandversion, trong đó trình duyệt có thể liệt kê khả năng tương thích của đối tượng đó với các thương hiệu đó. Bạn có thể truy cập trực tiếp vào mảng này hoặc bạn có thể sử dụng lệnh gọi some() để kiểm tra xem có mục nhập cụ thể nào hay không:

function isCompatible(item) {
  // In real life you most likely have more complex rules here
  return ['Chromium', 'Google Chrome', 'NewBrowser'].includes(item.brand);
}
if (navigator.userAgentData.brands.some(isCompatible)) {
  // browser reports as compatible
}

Nếu cần một trong các giá trị tác nhân người dùng chi tiết hơn, có độ hỗn loạn cao, bạn sẽ cần chỉ định giá trị đó và kiểm tra kết quả trong Promise được trả về:

navigator.userAgentData.getHighEntropyValues(['model'])
  .then(ua => {
    // requested hints available as attributes
    const model = ua.model
  });

Bạn cũng có thể sử dụng chiến lược này nếu muốn chuyển từ quá trình xử lý phía máy chủ sang quá trình xử lý phía máy khách. API JavaScript không yêu cầu quyền truy cập vào tiêu đề yêu cầu HTTP, vì vậy, bạn có thể yêu cầu giá trị tác nhân người dùng bất cứ lúc nào.

Chiến lược: Tiêu đề tĩnh phía máy chủ

Nếu đang sử dụng tiêu đề yêu cầu User-Agent trên máy chủ và nhu cầu của bạn đối với dữ liệu đó tương đối nhất quán trên toàn bộ trang web, thì bạn có thể chỉ định gợi ý ứng dụng mong muốn dưới dạng một tập hợp tĩnh trong các phản hồi. Đây là một phương pháp tương đối đơn giản vì bạn thường chỉ cần định cấu hình ở một vị trí. Ví dụ: tiêu đề này có thể nằm trong cấu hình máy chủ web nếu bạn đã thêm tiêu đề vào đó, cấu hình lưu trữ hoặc cấu hình cấp cao nhất của khung hoặc nền tảng mà bạn sử dụng cho trang web của mình.

Hãy cân nhắc chiến lược này nếu bạn đang chuyển đổi hoặc tuỳ chỉnh các phản hồi được phân phát dựa trên dữ liệu của tác nhân người dùng.

Trình duyệt hoặc các ứng dụng khác có thể chọn cung cấp các gợi ý mặc định khác nhau, vì vậy, bạn nên chỉ định mọi thứ bạn cần, ngay cả khi thông tin đó thường được cung cấp theo mặc định.

Ví dụ: các giá trị mặc định hiện tại cho Chrome sẽ được biểu thị như sau:

⬇️ Tiêu đề phản hồi

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA

Nếu cũng muốn nhận được mẫu thiết bị trong các phản hồi, bạn sẽ gửi:

⬇️ Tiêu đề phản hồi

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA

Khi xử lý việc này ở phía máy chủ, trước tiên, bạn nên kiểm tra xem tiêu đề Sec-CH-UA mong muốn đã được gửi hay chưa, sau đó chuyển sang phân tích cú pháp tiêu đề User-Agent nếu không có.

Chiến lược: Uỷ quyền gợi ý cho các yêu cầu trên nhiều nguồn gốc

Nếu yêu cầu tài nguyên phụ trên nhiều nguồn gốc hoặc trên nhiều trang web yêu cầu gửi Gợi ý cho ứng dụng tác nhân người dùng theo yêu cầu của chúng, thì bạn cần chỉ định rõ các gợi ý mong muốn bằng Chính sách quyền.

Ví dụ: giả sử https://blog.site lưu trữ tài nguyên trên https://cdn.site. Tài nguyên này có thể trả về tài nguyên được tối ưu hoá cho một thiết bị cụ thể. https://blog.site có thể yêu cầu gợi ý Sec-CH-UA-Model, nhưng cần uỷ quyền rõ ràng gợi ý đó cho https://cdn.site bằng cách sử dụng tiêu đề Permissions-Policy. Danh sách các gợi ý do chính sách kiểm soát có trong Bản nháp về cơ sở hạ tầng gợi ý của ứng dụng

⬇️ Phản hồi từ blog.site uỷ quyền gợi ý

Accept-CH: Sec-CH-UA-Model
Permissions-Policy: ch-ua-model=(self "https://cdn.site")

⬆️ Yêu cầu đối với tài nguyên phụ trên cdn.site bao gồm gợi ý được uỷ quyền

Sec-CH-UA-Model: "Pixel 5"

Bạn có thể chỉ định nhiều gợi ý cho nhiều nguồn gốc, chứ không chỉ từ phạm vi ch-ua:

⬇️ Phản hồi từ blog.site uỷ quyền nhiều gợi ý cho nhiều nguồn gốc

Accept-CH: Sec-CH-UA-Model, DPR
Permissions-Policy: ch-ua-model=(self "https://cdn.site"),
                    ch-dpr=(self "https://cdn.site" "https://img.site")

Chiến lược: Uỷ quyền gợi ý cho iframe

Iframe trên nhiều nguồn gốc hoạt động tương tự như tài nguyên trên nhiều nguồn gốc, nhưng bạn chỉ định các gợi ý mà bạn muốn uỷ quyền trong thuộc tính allow.

⬇️ Phản hồi của blog.site

Accept-CH: Sec-CH-UA-Model

↪️ HTML cho blog.site

<iframe src="https://widget.site" allow="ch-ua-model"></iframe>

⬆️ Yêu cầu gửi đến widget.site

Sec-CH-UA-Model: "Pixel 5"

Thuộc tính allow trong iframe sẽ ghi đè mọi tiêu đề Accept-CHwidget.site có thể tự gửi, vì vậy, hãy đảm bảo bạn đã chỉ định mọi thứ mà trang web trong iframe sẽ cần.

Chiến lược: Gợi ý động phía máy chủ

Nếu có những phần cụ thể trong hành trình của người dùng mà bạn cần nhiều gợi ý hơn so với phần còn lại của trang web, bạn có thể chọn yêu cầu các gợi ý đó theo yêu cầu thay vì tĩnh trên toàn bộ trang web. Việc này phức tạp hơn để quản lý, nhưng nếu bạn đã đặt các tiêu đề khác nhau trên mỗi tuyến, thì việc này có thể khả thi.

Điều quan trọng cần nhớ ở đây là mỗi thực thể của tiêu đề Accept-CH sẽ ghi đè hiệu quả tập hợp hiện có. Vì vậy, nếu bạn đang đặt tiêu đề một cách linh động, thì mỗi trang phải yêu cầu toàn bộ bộ gợi ý bắt buộc.

Ví dụ: bạn có thể có một phần trên trang web mà bạn muốn cung cấp các biểu tượng và chế độ điều khiển phù hợp với hệ điều hành của người dùng. Để làm việc này, bạn có thể muốn thêm Sec-CH-UA-Platform-Version để phân phát các tài nguyên phụ thích hợp.

⬇️ Tiêu đề phản hồi cho /blog

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA

⬇️ Tiêu đề phản hồi cho /app

Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA

Chiến lược: Yêu cầu gợi ý phía máy chủ trong yêu cầu đầu tiên

Có thể có trường hợp bạn cần nhiều hơn bộ gợi ý mặc định trong yêu cầu đầu tiên, tuy nhiên trường hợp này hiếm khi xảy ra, vì vậy, hãy đảm bảo bạn đã xem xét lý do.

Yêu cầu đầu tiên thực sự có nghĩa là yêu cầu cấp cao nhất đầu tiên cho nguồn gốc đó được gửi trong phiên duyệt web đó. Bộ gợi ý mặc định bao gồm tên trình duyệt với phiên bản chính, nền tảng và chỉ báo thiết bị di động. Vậy câu hỏi đặt ra ở đây là bạn có yêu cầu dữ liệu mở rộng trong lần tải trang đầu tiên không?

Để biết thêm gợi ý về yêu cầu đầu tiên, bạn có hai lựa chọn. Trước tiên, bạn có thể sử dụng tiêu đề Critical-CH. Phương thức này có định dạng giống như Accept-CH nhưng cho trình duyệt biết rằng trình duyệt phải thử lại yêu cầu ngay lập tức nếu yêu cầu đầu tiên được gửi mà không có gợi ý quan trọng.

⬆️ Yêu cầu ban đầu

[With default headers]

⬇️ Tiêu đề phản hồi

Accept-CH: Sec-CH-UA-Model
Critical-CH: Sec-CH-UA-Model

🔃 Trình duyệt thử lại yêu cầu ban đầu bằng tiêu đề bổ sung

[With default headers + …]
Sec-CH-UA-Model: Pixel 5

Điều này sẽ gây ra hao tổn khi thử lại trên yêu cầu đầu tiên, nhưng chi phí triển khai tương đối thấp. Hãy gửi tiêu đề bổ sung và trình duyệt sẽ thực hiện phần còn lại.

Đối với những trường hợp bạn thực sự cần thêm gợi ý trong lần tải trang đầu tiên, Đề xuất về độ tin cậy của gợi ý cho ứng dụng sẽ đưa ra một tuyến để chỉ định gợi ý trong chế độ cài đặt cấp kết nối. Thao tác này sử dụng tiện ích Cài đặt giao thức lớp ứng dụng(ALPS) cho TLS 1.3 để cho phép truyền sớm các gợi ý về kết nối HTTP/2 và HTTP/3. Việc này vẫn đang ở giai đoạn rất sớm, nhưng nếu bạn chủ động quản lý các chế độ cài đặt TLS và kết nối của riêng mình, thì đây là thời điểm lý tưởng để đóng góp.

Chiến lược: Hỗ trợ phiên bản cũ

Có thể bạn có mã cũ hoặc mã của bên thứ ba trên trang web phụ thuộc vào navigator.userAgent, bao gồm cả các phần của chuỗi tác nhân người dùng sẽ bị rút gọn. Về lâu dài, bạn nên chuyển sang các lệnh gọi navigator.userAgentData tương đương, nhưng có một giải pháp tạm thời.

UA-CH retrofill là một thư viện nhỏ cho phép bạn ghi đè navigator.userAgent bằng một chuỗi mới được tạo từ các giá trị navigator.userAgentData được yêu cầu.

Ví dụ: mã này sẽ tạo một chuỗi user-agent (trình đại diện người dùng) bao gồm cả gợi ý "model" (mô hình):

import { overrideUserAgentUsingClientHints } from './uach-retrofill.js';
overrideUserAgentUsingClientHints(['model'])
  .then(() => { console.log(navigator.userAgent); });

Chuỗi kết quả sẽ hiển thị mô hình Pixel 5, nhưng vẫn hiển thị 92.0.0.0 rút gọn vì không yêu cầu gợi ý uaFullVersion:

Mozilla/5.0 (Linux; Android 10.0; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.0.0 Mobile Safari/537.36

Yêu cầu hỗ trợ thêm

Nếu các chiến lược này không phù hợp với trường hợp sử dụng của bạn, vui lòng bắt đầu một Cuộc thảo luận trong kho lưu trữ hỗ trợ nhà phát triển hộp cát về quyền riêng tư để chúng ta cùng tìm hiểu vấn đề của bạn.

Ảnh chụp của Ricardo Rocha trên Unsplash