用户代理客户端提示:替代用户代理或新的数据源
2026/1/26


Markus_automation
Expert in data parsing and automation
每个HTTP请求都包含一组头信息,这些头信息传递有关客户端的信息到服务器。其中一个头信息是User-Agent。历史上,它是一个包含浏览器名称、版本、操作系统,甚至设备型号的长字符串。开发人员使用这个字符串为不同的浏览器服务不同版本的网站。
客户端提示是一个HTTP扩展,它允许浏览器仅在明确请求下提供有关自身的提示给服务器。浏览器不再被动地在User-Agent字符串中发送所有数据,只有在服务器返回包含所需头信息的Accept-CH头以后,才会将这些头信息添加到后续请求中。
目前,被超过75%的互联网用户使用的浏览器支持客户端提示。实际上,这直接影响了解析器、反欺诈系统和指纹识别在当今的工作方式,因为传统的解析User-Agent方法变得不再可靠。正确处理UA-CH使得在开发解析器和用户检测逻辑时,能够在保持更高准确性和控制力的同时获得相同数据。考虑UA-CH对于指纹识别也很重要,因为如果不考虑UA-CH就伪造单个UA可能导致不一致。
在本文中,我们将分解UA-CH协议的工作原理,并分享实用建议。
每个HTTP请求都包含一组头信息,这些头信息传递有关客户端的信息到服务器。其中一个头信息是User-Agent。历史上,它是一个包含浏览器名称、版本、操作系统,甚至设备型号的长字符串。开发人员使用这个字符串为不同的浏览器服务不同版本的网站。
客户端提示是一个HTTP扩展,它允许浏览器仅在明确请求下提供有关自身的提示给服务器。浏览器不再被动地在User-Agent字符串中发送所有数据,只有在服务器返回包含所需头信息的Accept-CH头以后,才会将这些头信息添加到后续请求中。
目前,被超过75%的互联网用户使用的浏览器支持客户端提示。实际上,这直接影响了解析器、反欺诈系统和指纹识别在当今的工作方式,因为传统的解析User-Agent方法变得不再可靠。正确处理UA-CH使得在开发解析器和用户检测逻辑时,能够在保持更高准确性和控制力的同时获得相同数据。考虑UA-CH对于指纹识别也很重要,因为如果不考虑UA-CH就伪造单个UA可能导致不一致。
在本文中,我们将分解UA-CH协议的工作原理,并分享实用建议。
内容
客户端提示和用户代理客户端提示
尽管客户端提示机制早在2013年就出现了,但它最初用于优化内容交付,并不涉及浏览器识别。只有在用户代理客户端提示引入后,它才开始被视为标准用户代理的替代方案。
客户端提示方法在基于Chromium的浏览器中实现:服务器请求提示,浏览器决定返回什么。这意味着默认情况下,浏览器不会发送任何额外数据,只提供服务器明确请求的信息。最简单的例子是开发者可以避免复杂的用户代理字符串解析,而是使用简单的头信息,而无需依赖正则表达式。

随着时间的推移,用户代理积累了细节和遗留的解决方法,比如Mozilla/5.0(这一特定条目自1990年代以来就存在)。这导致:
解析复杂性。由于用户代理格式没有标准化,解析字符串需要使用正则表达式,而这并不总是可靠的。难以阅读的用户代理字符串成为错误和兼容性问题的来源。
隐私数据泄露。用户代理传输大量信息,并随每个请求发送。这些细节允许用户跟踪:确切的浏览器版本、设备型号和位数都被跟踪器用于指纹识别。
如您所见,迫切需要用一种既有结构又由服务器控制的新机制取代用户代理,同时保持兼容性并提高隐私性。
接下来我们将使用术语熵。在UA-CH的背景下,它指的是传输信息的唯一程度。参数集的熵越高,浏览器拥有唯一指纹的可能性就越高,这反过来有助于反欺诈系统在众多配置文件中识别它。
用户代理客户端提示(UA-CH)是一组专用客户端提示,用于传输浏览器和设备特征。浏览器不再发送单一UA字符串,而是发送一组具有Sec-CH-UA-*前缀的结构化头信息,包括:
Sec-CH-UA— 浏览器品牌及其版本的列表。Sec-CH-UA-Mobile ?0或?1— 指示当前浏览器是否被视为移动设备。Sec-CH-UA-Platform— 操作系统名称(Windows、Android、macOS)。Sec-CH-UA-Platform-Version,Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-Model,Sec-CH-UA-Full-Version-List— 高熵提示,提供精确的操作系统版本、架构和设备型号。它们可能揭示更多独特信息,因此只有在服务器明确请求后才发送。
某些提示被认为是低熵:它们立即发送,并且不提供独特的信息(浏览器品牌、平台、移动指示器)。

高熵提示(操作系统精确版本、设备型号、架构和位数)只有在浏览器收到显式的Accept-CH请求后才发送,因为它们提供了更多的独特数据。这样,UA-CH能够比用户代理在更注重隐私和服务器控制的方式下传输相同甚至更多的信息。不过,“控制”这一点被稍显夸大了,因为从技术上讲,UA-CH可以通过额外请求传输比单一用户代理更多的信息,并且没有任何东西可以阻止服务器请求所有这些信息。从数据处理的角度来看,UA-CH比一长串字符串更方便和结构化,但隐私问题仍然存在。
客户端提示交换的工作原理
实际上,UA-CH生命周期看起来像这样:
首次请求
在首次请求时,浏览器默认会将低熵提示添加到头信息中:
Sec-CH-UA: "Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24" Sec-CH-UA-Mobile: ?0 Sec-CH-UA-Platform: "Windows"
这是关于浏览器品牌和操作系统的基本数据集。
服务器响应
在其响应中,服务器可以指定一个Accept-CH头信息,列出它需要的其他提示。例如:
Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch, Sec-CH-UA-Model
这是一个请求操作系统版本、架构和型号的命令。浏览器随后会缓存此需求,并在后续对同一域的请求中添加这些头信息。
后续请求
后续请求将变得如下所示:
Sec-CH-UA-Platform-Version: "10.0" Sec-CH-UA-Arch: "x86" Sec-CH-UA-Model: ""
最终,服务器在第一次请求时只能接收到一般信息,而其他所有信息是在Accept-CH请求后在后续导航中添加的。
为了使CDN和代理能够正确缓存不同内容版本,服务器还必须添加Vary: Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch。例如,如果网站为ARM和x86提供不同的JavaScript构建,则这是必要的。
JavaScript API 如何处理?
除了HTTP头信息外,UA-CH提示也可以在浏览器JavaScript中使用。在基于Chromium的浏览器中,有一个navigator.userAgentData对象,它立即提供低熵数据:
const brands = navigator.userAgentData?.brands; // [{brand: 'Chromium', version: '137'}, ...] const mobile = navigator.userAgentData?.mobile; // true/false const platform = navigator.userAgentData?.platform; // "Windows"

要获取详细的(高熵)字段,一个承诺——描述如何处理数据的特殊对象——被调用:
navigator.userAgentData.getHighEntropyValues([ 'architecture','bitness','model','platformVersion','fullVersionList','wow64' ]).then(ua => { console.log(ua.architecture); // "x86" console.log(ua.bitness); // "64" console.log(ua.platformVersion); // "10.0" console.log(ua.model); // device model or empty console.log(ua.fullVersionList); // array of full versions });

需要注意的是,该API仅在Chromium浏览器中受支持(在Safari或Firefox中不可用),因此代码必须包括对传统navigator.userAgent的回退,至少在可预见的未来。在服务器端,也必须检查Sec-CH-UA-*头信息的存在,因为没有它们,你将不得不依赖于解析旧的用户代理。

用户代理 vs UA-CH
让我们看看经典用户代理与新的客户端提示方法之间的关键差异:
特点 | 用户代理 | UA-CH(客户端提示) |
格式 | 一个长字符串 | 一组结构化头信息 |
传输 | 每个请求始终发送 | 仅发送服务器请求的字段 |
可扩展性 | 扩展困难,任何新参数可能破坏解析器 | 灵活,新的提示可以按需添加 |
服务器端解析 | 需要正则表达式 | 头信息可直接读取 |
浏览器支持 | 所有浏览器 | 基于Chromium的浏览器(Chrome 89+,Edge,Opera) |
首次加载准确性 | 立即传输全部信息 | 首次仅传输基本提示,细节之后 |
服务器控制 | 无 | 服务器决定请求哪些信息 |
指纹识别风险 | 高 | 降低,但未完全消除 |
格式:用户代理是一长串;UA-CH是一组结构化HTTP头信息(带
Sec-CH-UA-*前缀)。传输:用户代理随每个请求发送;UA-CH仅发送服务器明确请求的数据。浏览器本身决定在需要时添加哪些字段。
扩展性:经典用户代理难以扩展(任何新参数可能破坏解析器);UA-CH是一种更灵活的协议——新提示可以不破坏现有提示的情况下添加,因为服务器明确请求它们。
解析:用户代理字符串必须手动拆分并解析(使用正则表达式);UA-CH直接从头信息读取,简单且更可靠。
支持:所有浏览器都能理解用户代理;UA-CH默认在基于Chromium的浏览器中实现(Chrome 89+,Edge,Opera,Brave,Vivaldi,以及其他相同引擎的浏览器),但Safari和Firefox默认不支持。
首次加载准确性:经典用户代理立即提供全部信息;UA-CH首次请求仅提供基本提示,详细信息只有在服务器请求之后变得可用(在选择内容版本时需要考虑这一点)。
服务器控制:用户代理不允许服务器选择发送哪些数据——所有信息始终发送;使用UA-CH,服务器本身在
Accept-CH中决定需要哪些字段。指纹识别风险:UA-CH暴露给跟踪器的独特信息较少,但这并未消除其他用户唯一性方法(语言、时区、Canvas/WebGL等)。UA-CH仅在初期阶段减少了泄露的数据量,但未完全解决指纹识别问题。
总结而言,UA-CH允许以更有意图和注重隐私的方式收集所需信息,这简化了开发并增加了灵活性。然而,显然过渡需要时间。看起来混合方法会存在一段时间:在可以使用UA-CH的地方将使用它们,而其他地方将继续解析旧的用户代理。
实用建议
不要一次请求所有信息。如果您在
Accept-CH中指定所有提示,这开始变得像指纹识别。仅请求您实际需要的。例如,自适应图片受益于Sec-CH-Viewport-Width、Sec-CH-DPR和Sec-CH-Width;界面自适应使用Sec-CH-UA-Mobile和Sec-CH-UA-Platform;流量优化使用Sec-CH-Save-Data、Sec-CH-RTT和Sec-CH-ECT。避免不必要的探测,如一次请求所有设备和内存提示,因为这可能触发保护系统。不要忘记缓存。如果您根据客户端提示调整内容,请始终为这些头信息包括
Vary。例如,如果您通过Sec-CH-UA-Mobile和Sec-CH-Viewport-Width区分内容,响应必须包括Vary: Sec-CH-UA-Mobile, Sec-CH-Viewport-Width。否则,CDN或代理可能在未考虑所需提示的情况下缓存响应并提供错误版本。避免频繁更改。浏览器缓存
Accept-CH。不要在每个页面上请求不同的提示,因为这会增加头信息开销。回退是必须的。UA-CH尚未覆盖整个市场。默认情况下,最好读取
Sec-CH-UA-*或navigator.userAgentData,如果它们不可用,则回落到解析经典User-Agent。不要将UA-CH作为必需来源。
结论
用户代理客户端提示不只是另一个头信息,而是一种完全重新思考过时的单字符串模型的尝试。通过UA-CH,客户端数据以结构化和按需的方式传输,这:
简化了开发者的工作;
为行业进一步发展创造了机会。
对于反检测浏览器用户而言,UA-CH的关键优势在于必要信息与易用性之间的平衡。
客户端提示和用户代理客户端提示
尽管客户端提示机制早在2013年就出现了,但它最初用于优化内容交付,并不涉及浏览器识别。只有在用户代理客户端提示引入后,它才开始被视为标准用户代理的替代方案。
客户端提示方法在基于Chromium的浏览器中实现:服务器请求提示,浏览器决定返回什么。这意味着默认情况下,浏览器不会发送任何额外数据,只提供服务器明确请求的信息。最简单的例子是开发者可以避免复杂的用户代理字符串解析,而是使用简单的头信息,而无需依赖正则表达式。

随着时间的推移,用户代理积累了细节和遗留的解决方法,比如Mozilla/5.0(这一特定条目自1990年代以来就存在)。这导致:
解析复杂性。由于用户代理格式没有标准化,解析字符串需要使用正则表达式,而这并不总是可靠的。难以阅读的用户代理字符串成为错误和兼容性问题的来源。
隐私数据泄露。用户代理传输大量信息,并随每个请求发送。这些细节允许用户跟踪:确切的浏览器版本、设备型号和位数都被跟踪器用于指纹识别。
如您所见,迫切需要用一种既有结构又由服务器控制的新机制取代用户代理,同时保持兼容性并提高隐私性。
接下来我们将使用术语熵。在UA-CH的背景下,它指的是传输信息的唯一程度。参数集的熵越高,浏览器拥有唯一指纹的可能性就越高,这反过来有助于反欺诈系统在众多配置文件中识别它。
用户代理客户端提示(UA-CH)是一组专用客户端提示,用于传输浏览器和设备特征。浏览器不再发送单一UA字符串,而是发送一组具有Sec-CH-UA-*前缀的结构化头信息,包括:
Sec-CH-UA— 浏览器品牌及其版本的列表。Sec-CH-UA-Mobile ?0或?1— 指示当前浏览器是否被视为移动设备。Sec-CH-UA-Platform— 操作系统名称(Windows、Android、macOS)。Sec-CH-UA-Platform-Version,Sec-CH-UA-Arch,Sec-CH-UA-Bitness,Sec-CH-UA-Model,Sec-CH-UA-Full-Version-List— 高熵提示,提供精确的操作系统版本、架构和设备型号。它们可能揭示更多独特信息,因此只有在服务器明确请求后才发送。
某些提示被认为是低熵:它们立即发送,并且不提供独特的信息(浏览器品牌、平台、移动指示器)。

高熵提示(操作系统精确版本、设备型号、架构和位数)只有在浏览器收到显式的Accept-CH请求后才发送,因为它们提供了更多的独特数据。这样,UA-CH能够比用户代理在更注重隐私和服务器控制的方式下传输相同甚至更多的信息。不过,“控制”这一点被稍显夸大了,因为从技术上讲,UA-CH可以通过额外请求传输比单一用户代理更多的信息,并且没有任何东西可以阻止服务器请求所有这些信息。从数据处理的角度来看,UA-CH比一长串字符串更方便和结构化,但隐私问题仍然存在。
客户端提示交换的工作原理
实际上,UA-CH生命周期看起来像这样:
首次请求
在首次请求时,浏览器默认会将低熵提示添加到头信息中:
Sec-CH-UA: "Google Chrome";v="137", "Chromium";v="137", "Not/A)Brand";v="24" Sec-CH-UA-Mobile: ?0 Sec-CH-UA-Platform: "Windows"
这是关于浏览器品牌和操作系统的基本数据集。
服务器响应
在其响应中,服务器可以指定一个Accept-CH头信息,列出它需要的其他提示。例如:
Accept-CH: Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch, Sec-CH-UA-Model
这是一个请求操作系统版本、架构和型号的命令。浏览器随后会缓存此需求,并在后续对同一域的请求中添加这些头信息。
后续请求
后续请求将变得如下所示:
Sec-CH-UA-Platform-Version: "10.0" Sec-CH-UA-Arch: "x86" Sec-CH-UA-Model: ""
最终,服务器在第一次请求时只能接收到一般信息,而其他所有信息是在Accept-CH请求后在后续导航中添加的。
为了使CDN和代理能够正确缓存不同内容版本,服务器还必须添加Vary: Sec-CH-UA-Platform-Version, Sec-CH-UA-Arch。例如,如果网站为ARM和x86提供不同的JavaScript构建,则这是必要的。
JavaScript API 如何处理?
除了HTTP头信息外,UA-CH提示也可以在浏览器JavaScript中使用。在基于Chromium的浏览器中,有一个navigator.userAgentData对象,它立即提供低熵数据:
const brands = navigator.userAgentData?.brands; // [{brand: 'Chromium', version: '137'}, ...] const mobile = navigator.userAgentData?.mobile; // true/false const platform = navigator.userAgentData?.platform; // "Windows"

要获取详细的(高熵)字段,一个承诺——描述如何处理数据的特殊对象——被调用:
navigator.userAgentData.getHighEntropyValues([ 'architecture','bitness','model','platformVersion','fullVersionList','wow64' ]).then(ua => { console.log(ua.architecture); // "x86" console.log(ua.bitness); // "64" console.log(ua.platformVersion); // "10.0" console.log(ua.model); // device model or empty console.log(ua.fullVersionList); // array of full versions });

需要注意的是,该API仅在Chromium浏览器中受支持(在Safari或Firefox中不可用),因此代码必须包括对传统navigator.userAgent的回退,至少在可预见的未来。在服务器端,也必须检查Sec-CH-UA-*头信息的存在,因为没有它们,你将不得不依赖于解析旧的用户代理。

用户代理 vs UA-CH
让我们看看经典用户代理与新的客户端提示方法之间的关键差异:
特点 | 用户代理 | UA-CH(客户端提示) |
格式 | 一个长字符串 | 一组结构化头信息 |
传输 | 每个请求始终发送 | 仅发送服务器请求的字段 |
可扩展性 | 扩展困难,任何新参数可能破坏解析器 | 灵活,新的提示可以按需添加 |
服务器端解析 | 需要正则表达式 | 头信息可直接读取 |
浏览器支持 | 所有浏览器 | 基于Chromium的浏览器(Chrome 89+,Edge,Opera) |
首次加载准确性 | 立即传输全部信息 | 首次仅传输基本提示,细节之后 |
服务器控制 | 无 | 服务器决定请求哪些信息 |
指纹识别风险 | 高 | 降低,但未完全消除 |
格式:用户代理是一长串;UA-CH是一组结构化HTTP头信息(带
Sec-CH-UA-*前缀)。传输:用户代理随每个请求发送;UA-CH仅发送服务器明确请求的数据。浏览器本身决定在需要时添加哪些字段。
扩展性:经典用户代理难以扩展(任何新参数可能破坏解析器);UA-CH是一种更灵活的协议——新提示可以不破坏现有提示的情况下添加,因为服务器明确请求它们。
解析:用户代理字符串必须手动拆分并解析(使用正则表达式);UA-CH直接从头信息读取,简单且更可靠。
支持:所有浏览器都能理解用户代理;UA-CH默认在基于Chromium的浏览器中实现(Chrome 89+,Edge,Opera,Brave,Vivaldi,以及其他相同引擎的浏览器),但Safari和Firefox默认不支持。
首次加载准确性:经典用户代理立即提供全部信息;UA-CH首次请求仅提供基本提示,详细信息只有在服务器请求之后变得可用(在选择内容版本时需要考虑这一点)。
服务器控制:用户代理不允许服务器选择发送哪些数据——所有信息始终发送;使用UA-CH,服务器本身在
Accept-CH中决定需要哪些字段。指纹识别风险:UA-CH暴露给跟踪器的独特信息较少,但这并未消除其他用户唯一性方法(语言、时区、Canvas/WebGL等)。UA-CH仅在初期阶段减少了泄露的数据量,但未完全解决指纹识别问题。
总结而言,UA-CH允许以更有意图和注重隐私的方式收集所需信息,这简化了开发并增加了灵活性。然而,显然过渡需要时间。看起来混合方法会存在一段时间:在可以使用UA-CH的地方将使用它们,而其他地方将继续解析旧的用户代理。
实用建议
不要一次请求所有信息。如果您在
Accept-CH中指定所有提示,这开始变得像指纹识别。仅请求您实际需要的。例如,自适应图片受益于Sec-CH-Viewport-Width、Sec-CH-DPR和Sec-CH-Width;界面自适应使用Sec-CH-UA-Mobile和Sec-CH-UA-Platform;流量优化使用Sec-CH-Save-Data、Sec-CH-RTT和Sec-CH-ECT。避免不必要的探测,如一次请求所有设备和内存提示,因为这可能触发保护系统。不要忘记缓存。如果您根据客户端提示调整内容,请始终为这些头信息包括
Vary。例如,如果您通过Sec-CH-UA-Mobile和Sec-CH-Viewport-Width区分内容,响应必须包括Vary: Sec-CH-UA-Mobile, Sec-CH-Viewport-Width。否则,CDN或代理可能在未考虑所需提示的情况下缓存响应并提供错误版本。避免频繁更改。浏览器缓存
Accept-CH。不要在每个页面上请求不同的提示,因为这会增加头信息开销。回退是必须的。UA-CH尚未覆盖整个市场。默认情况下,最好读取
Sec-CH-UA-*或navigator.userAgentData,如果它们不可用,则回落到解析经典User-Agent。不要将UA-CH作为必需来源。
结论
用户代理客户端提示不只是另一个头信息,而是一种完全重新思考过时的单字符串模型的尝试。通过UA-CH,客户端数据以结构化和按需的方式传输,这:
简化了开发者的工作;
为行业进一步发展创造了机会。
对于反检测浏览器用户而言,UA-CH的关键优势在于必要信息与易用性之间的平衡。
随时获取最新的Octo Browser新闻
通过点击按钮,您同意我们的 隐私政策。
随时获取最新的Octo Browser新闻
通过点击按钮,您同意我们的 隐私政策。
随时获取最新的Octo Browser新闻
通过点击按钮,您同意我们的 隐私政策。



