---
url: 'https://www.corbado.com/zh/blog/client-hints-user-agent-chrome-safari-firefox'
title: 'Chrome、Safari和Firefox中的Client Hints与User-Agent'
description: '了解Chrome、Safari和Firefox对User-Agent和Client Hints API的支持，以及我们在JavaScript组件中如何利用它们进行通行密钥和设备检测。'
lang: 'zh'
author: 'Vincent Delitz'
date: '2026-07-27T08:24:20.151Z'
lastModified: '2026-07-27T08:25:49.213Z'
keywords: 'User-Agent精简, User-Agent, Client Hints, User-Agent Client Hints API, Client Hints API, 浏览器支持, User-Agent字符串, Chrome'
category: 'Engineering'
---

# Chrome、Safari和Firefox中的Client Hints与User-Agent

## Key Facts

- **User-Agent精简**已在所有主要浏览器中完成：Chrome和Edge自2023年起实施，Firefox部分实施，而Safari自2025年9月发布的iOS 26起已冻结。
- **Firefox不支持Client Hints**或`navigator.userAgentData`，这要求开发者在Mozilla的浏览器上退回到经典的User-Agent字符串解析。
- **`getHighEntropyValues()`** JavaScript API仅在Chromium浏览器中访问高熵设备数据。Safari和Firefox完全缺乏此API。
- 仅凭User-Agent字符串无法区分**Windows 10与Windows 11**。只有Chrome和Edge上的Client Hints才能揭示真实的平台版本。
- Corbado使用Client Hints来实现**通行密钥智能分析（passkey intelligence）**：检测新设备并评估跨设备身份验证的资格，特别是在区分Windows版本时。

## 1. 简介：什么是Client Hints和User-Agent精简？

检测和响应不同用户环境的方法在不断变化。传统上，**User-Agent字符串**一直是识别浏览器和设备信息的方式，允许网站相应地定制体验。然而，这些字符串经常被用于指纹识别，并在未经用户同意的情况下出于营销原因识别用户，从而引发了隐私担忧。

在这种背景下，**Client Hints作为JavaScript API**作为一种工具出现，它提供了一种更受控、更尊重隐私的方式来分享关于用户设备和偏好的必要信息。本文重点讨论**User-Agent精简的后果**，并探讨Client Hints如何帮助适应这种新情况。

我们将讨论的要点：

- **什么是User-Agent精简：**了解向精简User-Agent字符串转变的趋势及其影响。
- **Client Hints如何工作：**探讨Client Hints背后的机制以及如何有效地实现它们。

由于浏览器和操作系统有不同的立场并以不同的方式调整其方法，软件开发者面临着确保他们的应用程序仍然能够跨浏览器和操作系统准确检测和响应不同用户环境的挑战。

本文旨在全面概述这些变化，提供见解和实用指南，以帮助开发者，如果他们的用例或软件依赖于设备或操作系统的详细信息（例如详细的设备管理、检测已知设备、防欺诈或其他功能检测），或者像我们自己的情况一样，**使用User-Agent和Client Hints优化通行密钥体验**。

在我们深入探讨关于Client Hints的技术细节之前，我们将简要探讨User-Agent的历史以及不同的User-Agent精简工作是如何运作的。

### 1.1 User-Agent的简要历史

User-Agent字符串的历史可以追溯到早期网络浏览器的诞生。Tim Berners-Lee在1990年开发了第一个网络浏览器WorldWideWeb（后来改名为Nexus）。这很快被其他开创性的浏览器所跟进，如1991年的Line Mode Browser，随后出现了MidasWWW、ViolaWWW、Erwise和Cello等浏览器。

1993年，[NCSA Mosaic](https://en.wikipedia.org/wiki/NCSA_Mosaic)（通常简称为Mosaic）的发布，被认为是引发了网络普及的最初浪潮。Mosaic的User-Agent字符串非常简单，通常格式化为`NCSA_Mosaic/1.0`，包含产品名称后跟一个可选的斜杠和版本号。

最初，**引入User-Agent字段是出于分析目的并帮助发现问题**。在1992年的W3C HTTP档案中明确建议，在HTTP请求中“应该包含”这个字段。这个直截了当的字段提供了一种简单而有效的方式来传达产品名称和版本，有助于理解和排除与浏览器相关的问题。

随着网络的发展，User-Agent字符串的复杂性和使用量也在增加。它们变得更加详细，并开始包含大量关于浏览器、操作系统和设备的信息。虽然这些信息对于网络分析和优化用户体验很有价值，但它也带来了**重大的隐私担忧**。详细的User-Agent字符串**允许进行设备指纹识别**，使广告商和追踪者能够创建用户的唯一配置文件，并在不同网站上追踪他们的在线活动。

在现代，隐私已经成为用户和监管机构等的重要关注点，User-Agent字符串的详细性质越来越被视为存在问题。这种认识导致了降低User-Agent字符串粒度的努力，旨在在提供网络功能所需信息和保护用户隐私之间取得平衡。
这一转变标志着**User-Agent精简的开始，这是一种致力于最小化User-Agent字符串中共享的信息以降低隐私风险和增强安全性的运动**。

### 1.2 User-Agent精简和Client Hints简介

向User-Agent精简的转变始于对日益增长的隐私担忧的响应。以下是这一演变中关键里程碑的时间顺序概述：

#### 1.2.1 Safari中的User-Agent

2017年，苹果公司通过[著名的Twitter帖子](https://x.com/rmondello/status/943545865204989953)发起了User-Agent精简**运动**，宣布Safari将在Safari Technology Preview 46（STP 46）中冻结User-Agent字符串，旨在打击指纹识别并改善隐私。

![twitter safari user agent reduction](https://www.corbado.com/website-assets/twitter_user_agent_d4776d2a35.png)

然而，由于依赖最新User-Agent信息的网站存在重大的兼容性问题，该决定后来在2021年被部分撤回。

#### 1.2.2 Chrome（+ Edge）中的User-Agent

在2019/2020年，[谷歌宣布了计划](https://groups.google.com/a/chromium.org/g/blink-dev/c/-2JIRNMWJ7s/m/u-YzXjZ8BAAJ)，旨在降低Chrome中User-Agent字符串的粒度，引入了[User-Agent Client Hints (UA-CH)](https://chromestatus.com/feature/5704553745874944)作为一种灵活且受控的方式来请求特定的浏览器和设备信息。谷歌开始在Chrome Canary和Beta版本中测试User-Agent精简，收集反馈以确保兼容性和功能，并于[2023年](https://www.chromium.org/updates/ua-reduction/)在Android和所有其他Chrome平台上完成。与此同时，Chrome**引入了Client Hints**作为获取该信息的新方式。由于Microsoft Edge基于Chromium，因此Microsoft Edge在所有平台上的行为与Chrome相同。

#### 1.2.3 Firefox中的User-Agent

2021年，Mozilla加入了这项工作，逐渐降低User-Agent字符串的粒度，但Mozilla决定**在Firefox中不支持Client Hints**。

#### 1.2.4 今天的User-Agent（更新于2025年9月）

- **User-Agent精简因浏览器而异：** Chromium（Chrome，Edge）已实现完整的UA精简并支持Client Hints。然而，Safari使用其自己的冻结UA方法而未采用UA-CH，且Firefox尚未实现`navigator.userAgentData`。生态系统仍然是碎片化的。

- **Client Hints在Chromium中得到了发展：**所有浏览器仍然发送User-Agent标头，但在大多数浏览器中，它已被冻结在较旧的版本（见下表）。对于Chromium，可以使用Client Hints来获取更多信息。

让我们在下一章中看看浏览器目前发送什么作为User-Agent。

## 2. 什么是User-Agent精简？

在谈论User-Agent精简时，其含义是**减少**User-Agent字符串中的信息。让我们深入探讨一下在精简之前User-Agent中嵌入了什么。

### 2.1 什么是经典的User-Agent？

经典的User-Agent字符串通常包括以下组件，这些组件可用于检测功能：

`Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.2.1.0 Mobile Safari/537.36`

- **操作系统：**操作系统的名称（例如，Windows，macOS，Linux）。
- **操作系统版本号：**操作系统的特定版本。
- **浏览器名称：**浏览器的名称（例如，Chrome，Firefox，Safari）。
- **浏览器版本：**浏览器的特定版本。
- **架构：**系统的架构（例如，x86，ARM）。
- **设备类型/型号：**关于设备类型或型号的信息（例如，iPhone，Pixel）。
- **其他信息：**这可以包括诸如平台、构建号等附加详细信息。

#### 2.1.1 为什么使用User-Agent进行功能检测？

从历史上看，User-Agent字符串通常用于功能和平台检测，允许网站根据检测到的浏览器和设备特征定制其内容和功能（例如确定提供哪些特定二进制文件的下载）。随着手机和平板电脑的兴起，这变得尤为重要，对于尚未构建响应式的布局，以便能够将手机重定向到其特定版本。

然而，这种方法现在**被认为是次优的，因为它依赖于对浏览器功能的假设，而这些假设可能不成立或不够具体**。现代Web开发实践提倡在可能的情况下使用**通过浏览器API进行功能检测**，以直接检查特定的浏览器功能和能力。这种方法更可靠，并确保网站无论User-Agent字符串或浏览器版本如何都能正常工作。功能检测侧重于浏览器的实际能力，提供了一种更稳健、更面向未来的方式来处理浏览器行为和功能的差异。

到目前为止，这尚未完全可能，因为检测功能的新浏览器API在不同时间实施，并且通常在较大的团队（例如基于Chromium的浏览器）和较小的浏览器团队（例如Firefox）之间存在不同的方法。

#### 2.1.2 了解指纹识别中的熵：为什么提供大量信息是个问题？

更多的信息为网站提供了更广泛的可能性，以创建具有更高“熵”的指纹。在这种背景下，熵是指可用于在网站的不同访问者之间生成唯一指纹的变异量。

指纹可以用于不同目的。它可以用于保护目的，如检测欺诈和通过识别新设备来阻止帐户接管，但它也可以用于未经同意识别访问者或进行更具体的广告定位。

在User-Agent字符串的背景下，熵是指可用于跟踪和区分个体用户的高熵、可识别信息量。

- **高熵信息：**如特定的浏览器和操作系统版本，对用户指纹的唯一性贡献很大，使在不同网站上跟踪他们变得更容易。
- **低熵信息：**一般的浏览器名称或操作系统名称，提供较少详细的数据，对用户跟踪的贡献较小，因为携带这些组合的用户更多。

除User-Agent外，还有许多其他信息可用作熵的来源。例如，您可以在[https://coveryourtracks.eff.org](https://coveryourtracks.eff.org)上找到不同的熵来源。

### 2.2 降低User-Agent熵

因此，当浏览器谈论User-Agent精简时，它们主要针对降低高熵信息。以下是精简的不同示例：

#### 2.2.1 示例1：Chrome的User-Agent精简

以下是在Android手机上谷歌Chrome进行User-Agent精简的示例：

**之前：**
`Mozilla/5.0 (Linux; Android <span style={{color: '#016F01' }}>13; Pixel 7</span>) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.0.0 Mobile Safari/537.36`

**之后：**
`Mozilla/5.0 (Linux; Android <span style={{color: '#016F01' }}>10; K</span>) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.0.0 Mobile Safari/537.36`

User-Agent的格式保持不变，以免干扰库的现有解析逻辑。以下值被精简：

- 操作系统版本
- 浏览器次要版本
- 硬件模型 ![user agent](https://www.corbado.com/website-assets/user_agent_0fe7987aff.png)

该图详细说明了哪些值将继续根据操作系统更新，而绿色的值显示哪些值将在所有平台上保持不变。对于不同的操作系统值，只会有一个保持不变的变体可用：

| **操作系统** | **精简/固定名称**                 |
| -------------------- | --------------------------------- |
| Mac                  | Macintosh; Intel Mac OS X 10_15_7 |
| Windows              | Windows NT 10.0; Win64; x64       |
| ChromeOS             | X11; CrOS x86_64 14541.0.0        |
| Linux                | X11; Linux x86_64                 |
| Android              | Linux; Android 10; K              |
| iOS                  | 精简（iOS 26+）                   |

#### 2.2.2 示例2：Firefox User-Agent精简

下面，你将看到Mozilla Firefox User-Agent精简的示例，该示例遵循了谷歌在User-Agent精简方面的大部分立场。

以下是在Windows 11上运行当前Firefox版本的User-Agent示例：

`Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0`

在此User-Agent中，CPU架构、操作系统版本和浏览器次要版本已被冻结。

#### 2.2.3 示例3：macOS上的Safari User-Agent精简

下面，你将看到在macOS上的Safari User-Agent精简示例。

首先，让我们从Mac Silicon M2上**macOS Sonoma版本14.5上的Safari User-Agent**开始。

`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15`

你可以看到macOS版本被限制在`10_15_07`，并且架构也被固定为`Intel`，而不是报告Mac CPU架构。这对于macOS上的Firefox和[Chrome](https://issues.chromium.org/issues/40167872)也是如此。

#### 2.2.4 示例4：iOS上的Safari User-Agent（在iOS 26+中现已精简）

在iOS 26（2025年9月发布）之前，iOS上的Safari暴露了实际的操作系统版本。然而，**苹果现在已经在Safari 26中冻结了iOS/iPadOS的User-Agent**，类似于macOS。以下示例显示了iOS 26之前的User-Agent：

`Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Mobile/15E148 Safari/604.1`

**注意：**从iOS 26开始，iOS上的所有浏览器（Chrome，Firefox，Safari）现在都有冻结的User-Agent字符串，类似于macOS。以下示例显示了iOS 26之前的行为：

`Mozilla/5.0 (iPhone; CPU iPhone OS 17_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/126.0.6478.153 Mobile/15E148 Safari/604.1`

`Mozilla/5.0 (iPhone; CPU iPhone OS 17_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/127.1 Mobile/15E148 Safari/605.1.15`

### 2.3 User-Agent精简带来的检测限制

总的来说，很明显User-Agent专门针对高熵信息进行了精简。以下概述显示了在哪些平台/操作系统组合上User-Agent被精简。

| **浏览器**       | **Windows** | **MacOS** | **iOS**                  | **Android**                 |
| ---------------- | ----------- | --------- | ------------------------ | --------------------------- |
| Chrome           | 精简        | 精简      | 精简（iOS 26+）          | 精简                        |
| Edge             | 精简        | 精简      | 精简（iOS 26+）          | 精简                        |
| Firefox          | 精简        | 精简      | 精简（iOS 26+）          | 精简                        |
| Safari           | -           | 精简\*    | 精简（Safari 26+）\*\*   | -                           |
| Samsung Internet | -           | -         | -                        | 精简                        |
| WebViews         | -           | -         | 精简（iOS 26+）          | 未精简（≥ 16：精简）        |

因此，使用精简User-Agent时最重要的检测问题包括（* = 见下方有关macOS版本的备注）：

- **无法区分Windows 10和Windows 11：** 您无法再根据User-Agent区分Windows 10和Windows 11系统。
- **无法区分Android设备和操作系统版本：** 与苹果形成对比的是，Android曾经在User-Agent中包含实际的硬件型号。现在不再如此了。因此，仅通过User-Agent无法再区分不同的硬件型号。而在苹果设备上，这从来都不可能。
- **无法区分macOS版本和架构：** 无法根据User-Agent区分macOS版本和平台架构。
- **（*）Safari上的macOS版本：** Safari已冻结操作系统版本，但继续显示Safari版本。在撰写本文时，对于10.15及以上版本，可以安全地从Safari版本中减去3来检测macOS的主要版本。
- **（**）Safari 26+上的iOS版本：** 截至iOS 26（2025年9月），苹果冻结了iOS/iPadOS的User-Agent，类似于macOS。操作系统版本不再被暴露。

这是一张将macOS版本映射到其相应Safari版本的表格：

| **macOS版本**          | **Safari版本**     | **发布年份**     |
| ---------------------- | ------------------ | ---------------- |
| macOS Sequoia (15)     | Safari 18          | 2024             |
| macOS Sonoma (14)      | Safari 17          | 2023             |
| macOS Ventura (13)     | Safari 16          | 2022             |
| macOS Monterey (12)    | Safari 15          | 2021             |
| macOS Big Sur (11)     | Safari 14          | 2020             |
| macOS Catalina (10.15) | Safari 13          | 2019             |

还有其他基于复杂指纹识别技术的方法来检测操作系统和浏览器，比如TLS指纹识别。因为在合法的场景下，更深层次的操作系统检测是有意义的，谷歌引入了Client Hints，以便能够以编程方式接收这些信息。我们将在下一章中看到Client Hints是如何工作的。

## 3. Client Hints是如何工作的？

Client Hints使网站能够以尊重隐私的方式访问从User-Agent字符串中删除的高熵信息。访问Client Hints有两种主要方法：

- **HTTP标头**：使用HTTP请求标头，这仅适用于第一方上下文。
- **JavaScript API**：使用JavaScript API，可由嵌入式脚本使用。

Client Hints也可用于检索已包含在User-Agent中的低熵信息。这意味着在支持Client Hints的Chrome上，不再需要User-Agent。

### 3.1 存在哪些Client Hints？

根据使用的访问方法，Client Hints的命名略有不同。我们列出了最重要的Client Hints名称：
![client hints](https://s3.eu-central-1.amazonaws.com/corbado-cloud-staging-website-assets/client_hints_f186bae2e2.jpg)

| **HTTP UA-CH token**       | **UA-CH JS API**             | **熵**      |
| -------------------------- | ---------------------------- | ----------- |
| Sec-CH-UA-Platform-Version | UADataValues.platformVersion | 高          |
| Sec-CH-UA-Mobile           | NavigatorUAData.mobile       | 低          |
| Sec-CH-UA-Model            | UADataValues.model           | 高          |
| Sec-CH-UA                  | NavigatorUAData.brands       | 低          |
| Sec-CH-UA-Arch             | UADataValues.architecture    | 高          |

### 3.2 如何通过HTTP请求标头访问Client Hints

在第一方上下文中，网站可以使用HTTP请求标头请求有关用户浏览器和设备的特定信息。这种方法涉及在服务器的HTTP响应中设置正确的标头，指示服务器对哪些Client Hints感兴趣。然后浏览器在随后对同一源的请求中包含这些Hints。

这个标头通知浏览器在未来的请求中发送详细的用户信息，允许服务器相应地定制响应。这种方法确保只有第一方网站能够访问详细的用户信息，防止第三方资源获取高熵数据。有两种可用的请求标头，我们现在将讨论它们：

- 常规Client Hint标头
- 关键（Client）Hint标头

#### 3.2.1 如何使用常规Client Hint标头？

常规Client Hints是服务器可以从浏览器请求的标头，以**在随后的请求中**收集有关用户环境的信息。

**示例：在corbado.com上带有常规Client Hints的macOS 14.5上的Chrome**

1. 在对Corbado.com的第一个请求上，Chrome已经包含了以下低熵标头，因为这些信息也包含在User-Agent中。

| **标头**           | **值**                                                            |
| ------------------ | ----------------------------------------------------------------- |
| Sec-Ch-Ua          | "Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24" |
| Sec-Ch-Ua-Mobile   | ?0                                                                |
| Sec-Ch-Ua-Platform | "macOS"                                                           |

2. 假设Corbado.com想要在**随后的请求**中接收操作系统版本（平台版本）。因此，它将在对第一个请求的响应中设置适当的“Sec-CH-UA-Platform-Version”标头：

| **标头**   | **值**                     |
| ---------- | -------------------------- |
| Accept-CH  | Sec-CH-UA-Platform-Version |

3. 在**随后的请求**中，Corbado.com将收到一个带有平台版本的附加标头：

| **标头**           | **值**                                                            |
| ------------------ | ----------------------------------------------------------------- |
| Sec-Ch-Ua          | "Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24" |
| Sec-Ch-Ua-Mobile   | ?0                                                                |
| Sec-Ch-Ua-Platform | "macOS"                                                           |
| Sec-Ch-Ua-Platform-Version | "14.5.0"                                                          |

同时，该请求的User-Agent将保持不变（不包含平台版本）：

`Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36`

使用[https://user-agent-client-hints.glitch.me/headers](https://user-agent-client-hints.glitch.me/headers)，实际上可以尝试不同的常规Hints信息布局（记住**必须使用Chrome**）。有关详细信息，请参见[此处](https://github.com/WICG/ua-client-hints)。如果corbado.com在非常第一个页面请求时需要此信息，那么使用常规Client Hints就不够了，但是有一种方法可以通过关键（Client）Hints来加快这个过程。

#### 3.2.2 如何使用关键（Client）Hint标头？

假设[corbado.com](https://corbado.com)在第一个请求上需要平台版本，以呈现适合确切macOS版本的下载页面。它可以使用关键（client）hints，这将导致**立即重试请求**以仅渲染包含该标头的页面：

**示例：在corbado.com上带有关键Client Hints的macOS 14.5上的Chrome**

1. 在对corbado.com的第一个请求上，Chrome将已经包含以下低熵标头，因为这些信息也包含在User-Agent中。

| **标头**           | **值**                                                            |
| ------------------ | ----------------------------------------------------------------- |
| Sec-CH-UA          | "Google Chrome";v="125", "Chromium";v="125", "Not_A/Brand";v="24" |
| Sec-CH-UA-Mobile   | ?0                                                                |
| Sec-CH-UA-Platform | "macOS"                                                           |

2. 假设corbado.com想要在**页面的首次渲染**中接收操作系统版本（平台版本）。然后它将在对第一个请求的响应中设置关键client hint标头“Sec-CH-UA-Platform-Version”：

| **标头**   | **值**                     |
| ---------- | -------------------------- |
| Accept-CH  | Sec-CH-UA-Platform-Version |

3. Chrome将不会开始渲染并立即重试请求，以便**在首次渲染corbado.com时标头可用**。然后它将收到带有平台版本的附加标头：

| **标头**                   | **值**                                                            |
| -------------------------- | ----------------------------------------------------------------- |
| Sec-CH-UA                  | "Google Chrome";v="125", "Chromium";v="125", "Not_A/Brand";v="24" |
| Sec-CH-UA-Mobile           | ?0                                                                |
| Sec-CH-UA-Platform         | "macOS"                                                           |
| Sec-CH-UA-Platform-Version | "14.5.0"                                                          |

在下面的图表中，我们**看到了另一个示例**，网站请求设备模型作为Critical-CH标头的关键部分。正如我们所看到的，客户端像上面的例子那样重试请求（左侧序列图）。

![chromium user agent flow complete](https://www.corbado.com/website-assets/chromium_user_agent_flow_complete_cfbf688661.png)_Chromium的Client hints:
[https://developers.google.com/privacy-sandbox/protections/User-Agent](https://developers.google.com/privacy-sandbox/protections/User-Agent)_

因此，使用关键Client Hints会增加延迟，因为浏览器必须立即启动第二个请求以增加往返时间。有一种方法可以通过**促进TLS握手**（图表顶部的绿框）来优化传输以提前传输细节。这种促进**[ALPN](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation)（应用层协议协商）**的方法可以在[这里](https://docs.google.com/document/d/1HQd3vosjFls2jp6DwpkNMUN4CBdmmxZJJz0WhhcqOPw/edit)详细了解，但这超出了本文的范围。

为了使用标头接收附加信息，需要将配置添加到后端或网络服务器/负载均衡器。当您作为公司对网站拥有完全控制权时，这在第一方上下文中很容易完成。例如，corbado.com上的UI组件需要平台版本以提高我们的[通行密钥智能分析](https://docs.corbado.com/corbado-connect/features/passkey-intelligence)精度。开发者将我们的组件集成到各个页面中，如果要求他们添加标头然后将该信息传递给我们的组件将是令人不悦的开销。对于SPA和其他嵌入式JavaScript应用程序，可以使用另一个接口，这将在下一节中说明。

### 3.3 如何通过JavaScript API（嵌入式脚本）访问Client hints

使用[navigator.userAgentData.getHighEntropyValues()](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData/getHighEntropyValues)函数，也可以通过JavaScript API访问Client hints，这提供了一种灵活动态的方式来请求有关用户浏览器和设备的特定信息。这种方法涉及在网页的脚本中使用`navigator.userAgentData`对象来查询Client Hints。**这种方法不需要设置Client Hint标头，但它仅在支持`navigator.userAgentData`的浏览器（基于Chromium的浏览器，如Chrome和Edge）中起作用。Firefox和Safari不支持此API，因此开发者必须进行功能检测并提供回退方案。**

例如，在macOS的Chrome控制台中执行此代码时：

```javascript
if (navigator.userAgentData) {
    navigator.userAgentData
        .getHighEntropyValues(["architecture", "model", "platformVersion"])
        .then((ua) => {
            console.log(ua);
        });
}
```

当Promise解决时，返回相关信息。正如我们在上面所概述的，名称与标头不完全相同，但非常接近。

![platform version](https://www.corbado.com/website-assets/platform_version_6111c471f1.png)

然后返回的`platformVersion`可以在Promise中直接从嵌入的JavaScript代码中访问。此函数的覆盖率远低于实际的User-Agent精简：

![get high entropy list](https://www.corbado.com/website-assets/get_high_entropy_list_75834fcb30.png)

此外，由于苹果的限制，Chrome在iOS上并未提供此功能，因为它在iOS上部署了WebKit。

现在我们已经整理了有关User-Agent精简以及Client hints如何在Chrome中提供解决途径的最重要事实。

## 4. 当前处理User-Agent的建议

根据你的用例，你应该使用不同的方法以确保你的应用程序获得最佳可能结果：

- **功能检测：尽可能使用现有的浏览器JavaScript API**。只要可行，依靠浏览器API直接检测功能，而不是使用User-Agent。这更加可靠和面向未来。
- **对于低熵，如设备类型：User-Agent就足够了**。如果你的应用程序仅需要确定设备类型或其他低熵详细信息，User-Agent字符串就足够详细。你也可以使用现有的API来达到这些目的。
- **对于高熵信息和域控制：使用标头方法**。如果你需要详细信息并对该域具有控制权，请利用HTTP标头方法在受支持的地方（Chrome、Edge）请求高熵信息。在所有其他浏览器（不发送Client hint标头的浏览器）上使用经典User-Agent。根据你是需要立即获得信息还是可以承受轻微延迟，决定是否需要使用关键Client Hints。
- **对于JavaScript库：使用getHighEntropyValues**。如果你正在开发一个JavaScript库，最好的选择是在定义该函数时使用navigator.userAgentData.getHighEntropyValues()来动态请求有关用户浏览器和设备的特定信息，并在其他情况下回退到User-Agent解析库。

以下表格总结了如果你有权访问User-Agent（UA）和Client Hints（CH），你仍然可以在哪些地方检测操作系统版本：

| **浏览器**       | **Windows** | **MacOS**    | **iOS**         | **Android**      |
| ---------------- | ----------- | ------------ | --------------- | ---------------- |
| Chrome           | ✅ CH       | ✅ CH        | ❌ (iOS 26+)    | ✅ CH            |
| Edge             | ✅ CH       | ✅ CH        | ❌ (iOS 26+)    | ✅ CH            |
| Firefox          | ❌          | ❌           | ❌ (iOS 26+)    | ❌               |
| Safari           | -           | ✅ UA-Safari | ❌ (Safari 26+) | -                |
| Samsung Internet | -           | -            | -               | ✅ CH            |
| WebViews         | -           | -            | ❌ (iOS 26+)    | ✅ UA (≥ 16: ❌) |

通过根据你的具体需求选择合适的方法，你可以在获取详细用户信息的需求与隐私和性能考虑之间取得平衡。如果你高度依赖于难以提取或真正基于设备的信息，则回退到专业的库，如[wurfl](https://web.wurfl.io/)或[51degrees.com](https://51degrees.com)，它们会为你完成繁重的工作。这两个库都支持将Client hints集成到检测中，并且它们也有自己专有的方法甚至能检测iPhone型号。

## 5. 如何在通行密钥中使用User-Agent和Client Hints

在Corbado，我们专注于开发围绕主要由React开发的UI组件的通行密钥解决方案。我们的组件被嵌入到各种网站中，因此我们遵循自己的建议，在可用时使用getHighEntropyValues()，在所有其他情况下回退到经典的User-Agent解析。我们主要将此用于：

- **通行密钥管理：**在我们的通行密钥管理站点上，我们显示创建通行密钥设备的所有可用信息。
- **跨设备身份验证：**对于跨设备身份验证，我们使用关于操作系统的相关信息来确定客户端支持利用CDA的可能性。这在区分Windows 10和11时尤为重要，只有使用Chrome和Edge上的Client Hints才能实现：

![get high entropy value](https://www.corbado.com/website-assets/get_high_entropy_value_538459bd28.png)_更多详情请见：
[https://learn.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11](https://learn.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11)_

- **通行密钥智能分析：**我们认为平台应该决定是否应启动通行密钥登录。因此，我们将尽可能多的逻辑集成到我们的组件中，以检测是否使用了新设备。在这些场景中，新的或较小的操作系统版本是一个有价值的暗示，表明情况可能已发生变化。

当我们开始为组件编译信息时，我们发现了大量在User-Agent精简开始或之前产生的碎片化数据。因此，我们认为，一篇摘要对于希望改进检测但并不经常处理User-Agent或Client Hints的开发人员会有所帮助。

## 6. 结论

在基于User-Agent的检测成为数十年来的标准之后，为了保护用户隐私，User-Agent字符串变得不再那么详细。
在本文中，我们涵盖了：

- **什么是User-Agent精简？** User-Agent精简是通过最小化User-Agent字符串中共享的信息量以保护用户隐私的过程。这一转变降低了操作系统版本和硬件模型等数据的粒度，这些数据以前曾被用于在不同网站上对用户进行指纹识别和跟踪。我们探讨了这种缩减如何影响开发人员，以及他们如何适应该变化。
- **Client Hints如何工作？** Client Hints提供了一种机制，以一种更具隐私意识的方式请求有关用户设备的特定高熵信息。通过使用HTTP标头和JavaScript API，开发人员可以在必要时访问有关用户环境的详细数据。我们讨论了Client Hints的实现方式、可用的Hints类型，以及通过HTTP请求标头和JavaScript访问它们的方法。

Client Hints将继续发展，随着更多的浏览器和开发人员认识到它们的好处，它们的采用可能会增加。然而，它们的支持是否会变得普遍，或者Web是否会在这个主题上继续分化，仍有待观察。

## 常见问题解答

### 在iOS 26之后，我如何在Web应用中获取实际的iOS版本？

苹果在2025年9月发布的Safari 26中冻结了iOS/iPadOS的User-Agent字符串，这意味着操作系统版本不再通过运行在iOS上的任何浏览器的User-Agent暴露。与Android或桌面版的Chrome不同，iOS浏览器上没有可用的Client Hints API，因此实际的iOS版本不再可通过编程方式访问。

### 常规Client Hints和关键Client Hints之间有什么区别？

常规Client Hints通过`Accept-CH`响应标头请求，仅在随后的请求中包含，在初始页面加载时不可用。关键Client Hints（Critical Client Hints）触发在渲染之前立即进行浏览器重试，确保在首次渲染时Hint可用，但这会给请求周期增加一次往返延迟。

### 为什么苹果撤回了其最初在2017年做出的冻结Safari User-Agent的决定？

苹果于2017年在Safari Technology Preview 46中宣布冻结User-Agent，但在2021年由于依赖最新User-Agent信息的网站存在重大兼容性问题，部分撤回了该决定。随后，苹果实施了一种更渐进的冻结UA方法，而不是在当时立即完全冻结。

### 如果不支持Client Hints，我如何在Safari中检测macOS版本？

Safari不支持Client Hints，但macOS版本可以从User-Agent字符串中的Safari版本号推断出来。对于macOS 10.15及以上版本，根据Safari和macOS版本之间一致的发布对齐，从Safari主要版本减去三就能可靠地映射到macOS的主要版本。

### JavaScript库开发者应该使用什么方法进行跨浏览器设备检测？

推荐的方法是，当`navigator.userAgentData.getHighEntropyValues()`函数定义时调用它，以覆盖基于Chromium的浏览器，并在Firefox和Safari上回退到User-Agent字符串解析库。对于需要高度特定的设备模型识别的情况，如wurfl或51degrees等专业库提供了超出User-Agent字符串所能暴露的额外检测能力。
