Skip to content
ADP
API Design PrincipleBETA

[ADP-354] 客戶端提示

概述

客戶端提示是一種設計用來提供設備資訊的機制,使伺服器能夠為請求的客戶端做出最佳決策。它作為傳統 User-Agent 標頭的更優雅替代品,實現了主動(由客戶端驅動)的內容協商。

客戶端提示基礎設施

低熵提示

低熵提示是那些提供客戶端基本、非敏感資訊的提示:

高熵提示

高熵提示提供有關客戶端更詳細或潛在敏感的資訊。所有未被歸類為低熵的客戶端提示都屬於這一類別。

帶有客戶端提示的示例請求標頭

http
GET /data HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Host: api.example.com
Sec-CH-UA: "Chromium";v="110", "Not A(Brand";v="24", "Google Chrome";v="110"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36
downlink: 10
dpr: 2
rtt: 50
sec-ch-device-memory: 8
sec-ch-dpr: 2
sec-ch-viewport-width: 1280
viewport-width: 1280

伺服器與客戶端提示的交互

如果伺服器設計為與客戶端提示交互,它應該在回應中返回 Accept-CH 標頭,指定它接受哪些提示。然而,這需要額外的請求。或者,在支持客戶端提示的現代瀏覽器中,可以在文件標頭中包含一個元標籤,以跳過對帶有 Accept-CH 的伺服器回應的初始請求。

如果伺服器的 Accept-CH 與元標籤內容不同,瀏覽器會合併這些列表。

html
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Accept-CH" content="DPR, Viewport-Width, Width, Save-Data, Downlink, RTT, Sec-CH-UA-Full-Version, Sec-CH-UA-Platform-Version, Sec-CH-UA-Model">
    <title>客戶端提示測試</title>
</head>

指導原則

  • 應該(SHOULD)通過根據設備能力調整內容來改善用戶體驗
  • 應該(SHOULD)通過減少不必要的數據傳輸來提高性能
  • 應該(SHOULD)設計為增量式客戶端提示
    • 客戶端可能會限制通過客戶端提示發送的資訊;API 應該對客戶端提示的空值做出反應。
  • 應該(SHOULD)意識到與高熵客戶端提示相關的隱私問題
    • 首先使用低熵客戶端提示。
    • 如果 API 是與網頁一起構建的,可以實現客戶端提示偏好 UI,讓用戶選擇要發送的資訊。伺服器應該尊重這些偏好並限制 Accept-CH 的使用。
  • 應該(SHOULD)注意,預計瀏覽器會發送帶有低熵客戶端提示的 HTTP 請求,而無需在 Accept-CH 中指定它們。
  • 應該(SHOULD)意識到 Save-Data 是由用戶偏好定義的。參見 使用 Save-Data 交付快速輕量的應用程序

示例

設計基於客戶端提示的回應變化的 API

示例 1: 高 DPR 顯示器

http
GET /chart-data HTTP/1.1
Host: api.example.com
DPR: 2.0
http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 2048

{
  "chart": "高分辨率的數據"
}

示例 2: 慢速網絡連接

http
GET /data HTTP/1.1
Host: api.example.com
Downlink: 0.5
RTT: 100
http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1024

{
  "data": "由於網絡緩慢,返回完整數據的子集"
}

示例 3: 啟用 Save-Data

http
GET /articles/12345 HTTP/1.1
Host: api.example.com
Save-Data: on
http
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 1536

{
  "id": "12345",
  "title": "突發新聞:示例事件",
  "summary": "新聞事件的簡要摘要。",
  "content": "這是文章內容的濃縮版本...",
  "images": [
    "https://example.com/images/1-low-res.jpg"
  ]
}

參考資料

Changelog

  • 2024.09.24 Remove unwanted /api path in the samples