運用使用者代理程式用戶端提示,改善使用者隱私和開發人員體驗

User-Agent Client Hints 是 Client Hints API 的一項新擴充項目,讓開發人員能夠以保護隱私權和符合使用者需求的方式,存取使用者瀏覽器的相關資訊。

用戶端提示可讓開發人員主動要求有關使用者的裝置或條件的資訊,而不需要將其剖析出使用者代理程式 (UA) 字串。提供這個替代路徑是最終降低使用者代理程式字串精細程度的第一步。

瞭解如何更新需要剖析使用者代理程式字串的現有功能,才能改用使用者代理程式用戶端提示。

背景

網路瀏覽器發出要求時,會納入瀏覽器及其環境的相關資訊,以便伺服器啟用分析功能並自訂回應。這項定義在 1996 年的所有定義 (HTTP/1.0 的 RFC 1945),您可以在其中找到使用者代理程式字串的原始定義,其中包含範例:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

這個標頭旨在按照重要性、產品 (例如瀏覽器或資料庫) 和註解 (例如版本) 指定順序。

User-Agent 字串的狀態

在介入的延遲期間,這個字串已累積更多有關發出要求的用戶端額外詳細資料 (因為回溯相容而為相同)。在查看 Chrome 目前的 User-Agent 字串時,可看出:

Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4076.0 Mobile Safari/537.36

上述字串包含使用者的作業系統和版本、裝置型號、瀏覽器品牌與完整版本的相關資訊,足以推測出是行動瀏覽器,而不是為了歷史原因,提及其他瀏覽器的許多參照。

這些參數結合了可能的值多樣性,意味著 User-Agent 字串能包含足夠資訊,讓個別使用者能夠明確識別其身分。

User-Agent 字串可實現許多合法的用途,對開發人員和網站擁有者來說相當重要。不過,我們也務必要防止隱密追蹤方法保護使用者隱私,因此根據預設傳送通用 Analytics (分析) 資訊會違反該目標。

使用者代理程式字串也需要提高網頁相容性。這並非結構化,因此剖析會產生不必要的複雜性,通常是因為錯誤和網站相容性問題,對使用者有害。由於網站可能無法測試本身的設定,因此這些問題也會對較不常見的瀏覽器使用者造成負面影響。

全新的使用者代理程式用戶端提示隆重登場

使用者代理程式用戶端提示可讓使用者存取相同資訊,但能以更保護隱私權的方式存取,進而使瀏覽器最終減少 User-Agent 字串的預設廣播內容。用戶端提示會強制執行模型,伺服器必須要求瀏覽器提供一組有關用戶端的資料 (提示),且瀏覽器會套用自己的政策或使用者設定,以判斷傳回哪些資料。也就是說,預設不會公開「所有」使用者代理程式資訊,而是以明確且可稽核的方式管理存取權。開發人員也能受益於更簡單的 API,不必再使用規則運算式!

目前的用戶端提示組合主要說明瀏覽器的顯示與連線功能。您可以在使用用戶端提示自動選取資源一文中瞭解詳情,但以下說明相關流程。

伺服器會透過標頭要求特定的用戶端提示:

⬇️ 伺服器回應

Accept-CH: Viewport-Width, Width

或中繼標記:

<meta http-equiv="Accept-CH" content="Viewport-Width, Width" />

然後瀏覽器可以選擇在後續要求中傳回下列標頭:

🗓?️ 後續要求

Viewport-Width: 460
Width: 230

伺服器可以選擇變化自己的回應,例如以適當的解析度提供圖片。

User-Agent Client Hints 會擴大含有 Sec-CH-UA 前置字串的屬性範圍,您可透過 Accept-CH 伺服器回應標頭加以指定。如需所有詳細資料,請先參閱說明,接著深入瞭解完整提案

Chromium 89 版的使用者代理程式用戶端提示

自 89 版起,Chrome 已預設啟用「使用者代理程式用戶端提示」。

根據預設,如果用戶端是行動裝置,瀏覽器會傳回瀏覽器品牌、重要 / 主要版本、平台和指標:

❌️ 所有要求

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"

使用者代理程式回應與要求標頭

⬇️ 回應 Accept-CH
⬇️ 要求標頭
➜️ 要求
範例值
說明
Sec-CH-UA "Chromium";v="84",
"Google Chrome";v="84"
瀏覽器品牌清單及其重要版本。
Sec-CH-UA-Mobile ?1 布林值,指出瀏覽器是否在行動裝置上 (?1 代表 true) 或否 (?0 代表 false)。
Sec-CH-UA-Full-Version "84.0.4143.2" [已淘汰]瀏覽器的完整版本。
Sec-CH-UA-Full-Version-List "Chromium";v="84.0.4143.2",
"Google Chrome";v="84.0.4143.2"
瀏覽器品牌及其完整版本清單。
Sec-CH-UA-Platform "Android" 裝置的平台,通常是作業系統 (OS)。
Sec-CH-UA-Platform-Version "10" 平台或 OS 的版本。
Sec-CH-UA-Arch "arm" 裝置的基礎架構。儘管這可能與顯示網頁無關,不過網站會需要提供預設格式的下載項目。
Sec-CH-UA-Model "Pixel 3" 裝置型號。
Sec-CH-UA-Bitness "64" 基礎架構的位元程度 (即整數或記憶體位址的大小,以位元為單位)

廣告交易平台範例

廣告交易平台範例會像這樣:

🗓?️ 瀏覽器的初始要求
瀏覽器要求網站提供的 /downloads 頁面,並傳送預設的基本 User-Agent。

GET /downloads HTTP/1.1
Host: example.site

Sec-CH-UA: "Chromium";v="93", "Google Chrome";v="93", " Not;A Brand";v="99"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Platform: "Android"

⬇️ 伺服器回應
伺服器會傳回頁面,並額外要求瀏覽器完整版本和平台。

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Full-Version-List

❌️ 後續要求
瀏覽器會授權伺服器存取其他資訊,並在所有後續要求中傳回額外提示。

GET /downloads/app1 HTTP/1.1
Host: example.site

Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="98", "Google Chrome";v="98"
Sec-CH-UA-Mobile: ?1
Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"
Sec-CH-UA-Platform: "Android"

JavaScript API

除了標頭外,您也可以透過 navigator.userAgentData 在 JavaScript 中存取使用者代理程式。您可分別透過 brandsmobile 屬性,存取預設的 Sec-CH-UASec-CH-UA-MobileSec-CH-UA-Platform 標頭資訊:

// Log the brand data
console.log(navigator.userAgentData.brands);

// output
[
  {
    brand: 'Chromium',
    version: '93',
  },
  {
    brand: 'Google Chrome',
    version: '93',
  },
  {
    brand: ' Not;A Brand',
    version: '99',
  },
];

// Log the mobile indicator
console.log(navigator.userAgentData.mobile);

// output
false;

// Log the platform value
console.log(navigator.userAgentData.platform);

// output
"macOS";

其他值可透過 getHighEntropyValues() 呼叫存取。換句話說,「高熵」一詞是指「資訊熵」的參照,也就是這些值提供給使用者瀏覽器的資訊量。與要求額外的標頭相同,也會由瀏覽器傳回哪些值 (如果有的話)。

// Log the full user-agent data
navigator
  .userAgentData.getHighEntropyValues(
    ["architecture", "model", "bitness", "platformVersion",
     "fullVersionList"])
  .then(ua => { console.log(ua) });

// output
{
   "architecture":"x86",
   "bitness":"64",
   "brands":[
      {
         "brand":" Not A;Brand",
         "version":"99"
      },
      {
         "brand":"Chromium",
         "version":"98"
      },
      {
         "brand":"Google Chrome",
         "version":"98"
      }
   ],
   "fullVersionList":[
      {
         "brand":" Not A;Brand",
         "version":"99.0.0.0"
      },
      {
         "brand":"Chromium",
         "version":"98.0.4738.0"
      },
      {
         "brand":"Google Chrome",
         "version":"98.0.4738.0"
      }
   ],
   "mobile":false,
   "model":"",
   "platformVersion":"12.0.1"
}

操作示範

您可以在自己的裝置上試用標頭和 JavaScript API,前往 user-agent-client-hints.glitch.me

提示生活時間與重設

透過 Accept-CH 標頭指定的提示將在瀏覽器工作階段期間傳送,或直到指定不同的提示組合為止。

也就是說,如果伺服器傳送下列內容:

⬇️ 回覆

Accept-CH: Sec-CH-UA-Full-Version-List

接著,瀏覽器會對該網站的所有要求傳送 Sec-CH-UA-Full-Version-List 標頭,直到瀏覽器關閉為止。

🗓?️ 後續要求

Sec-CH-UA-Full-Version-List: " Not A;Brand";v="99.0.0.0", "Chromium";v="98.0.4738.0", "Google Chrome";v="98.0.4738.0"

然而,如果收到另一個 Accept-CH 標頭,則會完全取代瀏覽器正在傳送的提示。

⬇️ 回覆

Accept-CH: Sec-CH-UA-Bitness

🗓?️ 後續要求

Sec-CH-UA-Platform: "64"

你先前要求的「Sec-CH-UA-Full-Version-List不會傳送

建議您將 Accept-CH 標頭視為為該網頁指定所需的完整提示組合,讓瀏覽器接著針對該頁面的所有子資源傳送指定的提示。提示會留在下一個導覽頁面,但網站不應假設或認為提示會傳送。

您也可以在回應中傳送空白的 Accept-CH,藉此有效清除瀏覽器傳送的所有提示。建議您在使用者重設偏好設定或登出網站的任何一處加入這個標記。

這個模式也符合透過 <meta http-equiv="Accept-CH" …> 標記使用提示的方式。要求的提示只會在由網頁起始的要求時傳送,不會在任何後續瀏覽中傳送。

提示範圍和跨來源要求

根據預設,系統只會在相同來源的要求中傳送「用戶端提示」。也就是說,如果您在 https://example.com 上要求特定提示,但想要最佳化的資源在 https://downloads.example.com 上就「不會」收到任何提示,

如要允許跨來源要求提示,每個提示和來源都必須透過 Permissions-Policy 標頭指定。如要將其套用至使用者代理程式用戶端提示,您需要小寫提示,並移除 sec- 前置字串。例如:

⬇️ 來自「example.com」的回覆

Accept-CH: Sec-CH-UA-Platform-Version, DPR
Permissions-Policy: ch-ua-platform-version=(self "downloads.example.com"),
                    ch-dpr=(self "cdn.provider" "img.example.com");

❌️ 要求傳送至 downloads.example.com

Sec-CH-UA-Platform-Version: "10"

❌️ 要求 cdn.providerimg.example.com

DPR: 2

哪裡可以使用使用者代理程式用戶端提示?

快速解答是要把剖析使用者代理程式標頭的執行個體,或使用會存取相同資訊的任何 JavaScript 呼叫 (例如 navigator.userAgentnavigator.appVersionnavigator.platform) 時重構,才能改用使用使用者代理程式用戶端提示。

要進一步執行這項動作,請重新檢查您使用「使用者代理程式」資訊的方式,並盡可能將其替換為其他方法。一般來說,只要使用漸進式強化、特徵偵測或回應式設計,就能達成相同的目標。依賴 User-Agent 資料的基本問題在於,您一直在維護要檢查的屬性與其啟用的行為之間的對應關係。維護負擔是為了確保偵測的全面,並持續保持在最新狀態。

請記住,User-Agent Client Hints 存放區列出了一些適用於網站的有效用途

使用者代理程式字串會受到什麼影響?

我們打算降低現有使用者代理程式字串所公開的識別資訊數量,同時避免現有網站發生意外中斷,藉此盡可能降低隱密追蹤網頁的能力。隆重推出「使用者代理程式用戶端提示」,您可以在對使用者代理程式字串進行任何變更之前,先瞭解並試用這項新功能。

最終,系統會減少使用者代理程式字串中的資訊,以維持舊版格式,同時只提供與預設提示相同的高階瀏覽器和重要版本資訊。在 Chromium 中,這項變更已延後到至少 2022 年,以便生態系統有額外時間評估新的使用者代理程式用戶端提示功能。

您可以在 Chrome 93 中啟用 about://flags/#reduce-user-agent 旗標,藉此測試此版本的版本 (注意:在 Chrome 84 至 92 版中,此旗標稱為 about://flags/#freeze-user-agent)。基於相容性因素,會傳回包含歷史項目的字串,但包含制化細節。例如:

Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.0.0 Mobile Safari/537.36

縮圖由 Sergey ZolkinUnsplash 提供