返回博客

User-Agent 技术详解:从 UA 字符串、浏览器指纹到 Client Hints

从 HTTP 语义和真实 UA 拆解出发,结合浏览器指纹论文解释 UA 的信息量、伪装一致性风险、Chrome UA Reduction 与 Client Hints,并给出开发和多环境管理的实践方法。

User-Agent 技术详解:从 UA 字符串、浏览器指纹到 Client Hints

打开浏览器开发者工具,在网络请求里几乎总能看到一行 User-Agent。它看起来像浏览器的“自我介绍”:使用什么浏览器、运行在哪个系统、版本是多少。于是很多人会自然地把它理解成设备身份证,甚至认为改掉这一行,就能变成另一台设备。

这两个理解都只对了一半。

User-Agent(下文简称 UA)首先是一段由客户端主动声明的兼容信息。它不是可信身份凭证,内容可以被修改;但它又不是孤立存在的。网站可以把 UA 与 Client Hints、JavaScript API、屏幕、字体、Canvas、WebGL、网络和行为信号放在一起分析。真正值得研究的,不是“UA 能不能改”,而是它在整套浏览器可观察面中扮演什么角色。

本文从 HTTP 标准和浏览器指纹论文出发,回答四个核心问题:

  1. 一条 UA 字符串为什么像“浏览器考古现场”?
  2. UA 单独能提供多少识别信息,论文数据该如何解读?
  3. 为什么只改 UA 可能产生更明显的矛盾?
  4. UA Reduction 与 User-Agent Client Hints 到底改变了什么?

本文所说的 UA 主要指 HTTP 请求头 User-Agent,同时会讨论 JavaScript 中的 navigator.userAgentnavigator.userAgentData。它们属于相邻但不完全等价的接口,不能在所有浏览器和场景中假定内容永久一致。

一、User-Agent 到底是什么?

RFC 9110 第 10.1.5 节User-Agent 定义为请求方用于说明自身产品信息的字段。其简化语法是:

User-Agent = product *( RWS ( product / comment ) )
product    = token [ "/" product-version ]

换成日常语言,就是:先写一个产品名,可以带版本;后面继续追加产品或注释。标准允许它用于兼容性处理、问题诊断和统计,同时明确提醒实现方不要无必要地暴露过细信息,因为更长、更具体的 UA 会增加延迟和指纹风险。

一条现代 Chromium 桌面浏览器 UA 可能类似:

Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/145.0.0.0 Safari/537.36

将它按空格拆开,会发现很多看似“不属于 Chrome”的名字:

片段今天通常表达什么容易产生的误解
Mozilla/5.0历史兼容标记使用了 Firefox 或 Mozilla 浏览器
Windows NT 10.0Windows 平台类别;在缩减策略下不能可靠区分 Windows 10/11一定是 Windows 10
Win64; x6464 位 Windows / x86-64 架构线索足以证明真实 CPU 型号
AppleWebKit/537.36兼容性与引擎谱系标记当前 Chrome 仍直接使用 Safari 的完整实现
KHTML, like Gecko历史兼容标记同时运行 KHTML 和 Gecko
Chrome/145.0.0.0Chrome/Chromium 品牌与主版本;后三段可能被缩减能得到精确补丁版本
Safari/537.36为兼容旧站点保留的标记这一定是 Safari

UA 之所以冗长,是因为早期网站经常按浏览器名称分支。新浏览器为了拿到正确页面,只能声明自己“也兼容”旧浏览器。兼容标记逐层累积,最终形成一条不能按自然语言直读的历史记录。

所以,解析 UA 的第一原则是:它是一种兼容协议,不是一句严格的设备描述。

二、网站为什么仍然使用 UA?

UA 并非只服务于追踪。合理用途包括:

  • 对确实存在差异的旧浏览器提供兼容页面;
  • 选择合适的安装包或下载格式;
  • 在错误日志中定位特定浏览器版本的问题;
  • 粗粒度统计浏览器家族、平台类别和版本分布;
  • 发现明显不可能的自动化或恶意请求组合。

问题在于,UA 嗅探(UA sniffing)很容易从“兼容兜底”滑向“根据名称猜能力”。例如,代码看到 Chrome 就假定某个 API 一定存在,遇到内嵌 WebView、衍生浏览器、冻结版本或伪造 UA 时便会出错。

更稳妥的顺序是:

  1. 能做功能检测时,直接检查 API 或行为是否可用;
  2. 确需识别浏览器时,使用维护中的解析库,不手写脆弱正则;
  3. 只保留业务真正需要的粗粒度分类;
  4. 为未知品牌、未知版本和缺失字段准备回退路径。

三、UA 是浏览器指纹吗?

准确说,UA 是浏览器指纹的一项输入,通常不是完整指纹。

浏览器指纹的核心不是读取某个秘密编号,而是测量一组相对稳定、具有区分度的可观察属性。UA 可能提供浏览器家族、版本和平台线索;屏幕尺寸、字体、时区、Canvas、WebGL、AudioContext 等信号则从其他接口补充信息。

Laperdrix 等人的浏览器指纹综述将这类技术放在无状态识别的框架下讨论:网站不一定要先在设备上写入 Cookie,也可以根据浏览器暴露的属性组合来关联访问。这里的“无状态”不代表网站完全不保存数据,而是识别材料不必依赖客户端持久标识符。

1. 论文中的 10 bit 应该怎样理解?

Peter Eckersley 在 2010 年的 Panopticlick 研究 《How Unique Is Your Web Browser?》中,对约 47 万份浏览器指纹样本进行了测量。论文报告:

  • 完整指纹在该样本中的平均信息量约为 18.1 bit
  • 换算成直观概率,平均约为 286,777 个浏览器中才出现一次同样组合;
  • 表格中,UA 字符串这一项的平均信息量约为 10.0 bit
  • 在启用 Flash 或 Java 的浏览器中,94.2% 的完整指纹是唯一的。

信息量常用自信息表示:

I(x) = -log₂ P(x)

如果某种 UA 在总体中出现概率为 1/1024,它对应的信息量就是 10 bit。这里的 10 bit 不等于 UA 有 1024 种,也不等于它能唯一识别某个人;它表达的是观察到这一取值后,不确定性平均减少了多少。

2. 为什么不能把 2010 年数据直接当作今天的常数?

这组结果非常重要,但使用时至少要加上三层限定:

  • 样本来自主动访问隐私测试页面的人群,不是全球互联网的随机抽样;
  • 2010 年的浏览器、插件生态和 UA 版本颗粒度与今天不同;
  • Chrome 的 UA Reduction、插件接口收缩以及浏览器的反指纹策略已经改变了属性分布。

因此,论文数据适合证明“UA 与其他属性能够贡献可测量的区分信息”,不适合被改写成“今天 UA 固定有 10 bit 熵”。指纹能力取决于样本总体、时间窗口、浏览器策略和信号组合。

四、为什么只修改 UA 可能适得其反?

UA 是客户端声明,不带密码学证明。服务端无法从这一行直接读取一台设备的“出厂真相”。但是,网站可以检查不同信号是否合理相容。

User-Agent 与其他浏览器信号的一致性模型

例如,一条 UA 声称自己是移动浏览器,页面却观察到没有触控点、窗口尺寸长期像桌面显示器、相关 Client Hints 又报告桌面平台。单项数据都可能有正常例外,但多个稳定矛盾叠加,会形成可分类的模式。

早在 Panopticlick 论文中,研究者就观察到类似现象:有浏览器自称 iPhone 却支持 Flash,也有 Firefox UA 与仅 Internet Explorer 支持的存储特征同时出现。2018 年的 FP-Scanner 研究进一步系统化了这一问题:一些反指纹扩展或伪装工具会在不同接口间留下不一致,检测器可以识别属性被修改,有时还能推断原始浏览器或操作系统类别。

这并不意味着所有不一致都是恶意行为。远程桌面、辅助功能、企业策略、兼容层和特殊硬件都可能产生少见组合。严谨的风控系统应做概率判断,而不是用一条规则直接封禁用户。

从环境管理角度看,真正需要关注的是三件事:

  • 内部一致性:UA、Client Hints、平台、架构、触控和屏幕等信息不要明显互相否定;
  • 时间稳定性:同一个长期环境不应在每次启动时无缘无故剧烈变化;
  • 合理多样性:不同环境可以不同,但罕见且机械生成的组合未必更安全。

FP-STALKER研究浏览器指纹随时间演化时也说明,属性变化并不自动破坏关联。跟踪模型可以利用稳定属性与可解释的版本变化,将前后指纹重新连接起来。

五、UA Reduction 解决了什么问题?

传统 UA 默认随每次请求发送,任何收到请求的第一方或第三方资源都能被动读取。字段越具体,所有接收方获得的区分信息越多。

Chromium 的 User-Agent Reduction 计划采用了“减少默认颗粒度”的思路:

  • 从 Chrome 101 开始,将桌面 UA 的次版本、构建号和补丁号缩减为 0.0.0
  • 后续阶段逐步统一桌面操作系统版本、CPU 和 Android 设备信息;
  • Android 的缩减 UA 使用固定的平台与机型表示,例如 Android 10; K
  • 需要更细信息的站点改用 User-Agent Client Hints 按需请求。

缩减后的典型格式可以抽象为:

Mozilla/5.0 (<统一后的平台信息>)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/<主版本>.0.0.0 Safari/537.36

这项改变降低了传统 UA 的被动指纹面,但没有消灭浏览器指纹。主版本、平台类别和移动设备标记仍可能可见;网页也仍可从其他 API、网络和行为中获得信息。

六、User-Agent Client Hints 如何工作?

Client Hints 的基本机制由 RFC 8942定义;UA 专用字段由 WICG 的 User-Agent Client Hints 草案继续描述。它把原来塞在一条非结构化字符串里的信息拆成结构化字段,并区分默认可发送的低熵提示与需要站点请求的高熵提示。

UA Reduction 与 User-Agent Client Hints 的请求流程

一个简化的交互可能是:

GET /download HTTP/1.1
User-Agent: Mozilla/5.0 (...) Chrome/145.0.0.0 Safari/537.36
Sec-CH-UA: "Chromium";v="145", "Not_A Brand";v="99"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "Windows"

服务器确实需要架构与位数来选择安装包时,可以在响应中声明:

HTTP/1.1 200 OK
Accept-CH: Sec-CH-UA-Arch, Sec-CH-UA-Bitness
Vary: Sec-CH-UA-Arch, Sec-CH-UA-Bitness

浏览器在支持该机制、满足安全与策略要求时,可以在后续请求中附带:

Sec-CH-UA-Arch: "x86"
Sec-CH-UA-Bitness: "64"

常见 UA Client Hints 包括:

字段典型用途信息级别
Sec-CH-UA品牌及主要版本列表通常为低熵
Sec-CH-UA-Mobile是否偏向移动设备通常为低熵
Sec-CH-UA-Platform平台类别通常为低熵
Sec-CH-UA-ArchCPU 架构高熵,按需请求
Sec-CH-UA-Bitness体系结构位数高熵,按需请求
Sec-CH-UA-Platform-Version平台版本高熵,按需请求
Sec-CH-UA-Full-Version-List各品牌完整版本高熵,按需请求
Sec-CH-UA-Model设备型号高熵,按需请求

这里有三个容易被忽略的工程细节。

1. Client Hints 不是所有请求都自动完整发送

低熵提示可能默认出现,高熵提示通常需要站点通过 Accept-CH 请求。首次导航、子资源、权限策略、HTTPS 环境和浏览器支持情况都会影响实际结果,因此服务端必须允许字段缺失。

2. 品牌列表故意要求解析器更健壮

Sec-CH-UA 可能包含多个品牌和一个用于测试兼容性的非真实品牌。代码不能假定第一个品牌永远是产品名,也不能因为出现未知品牌就报错。正确做法是解析结构化字段、忽略不认识的项,并为未来品牌保留扩展空间。

3. 用 Client Hints 改变响应时要处理缓存

如果服务器根据架构、平台等提示返回不同内容,应正确设置 Vary 或采用等价的缓存键策略。否则,共享缓存可能把为一种设备生成的响应错误地发给另一种设备。

七、Client Hints 是否比传统 UA 更隐私?

答案是:它改善了信息暴露方式,但不是隐私免疫机制。

传统 UA 的问题在于“默认、被动、一次性暴露一大串”。Client Hints 的改进是将信息拆分,让高熵字段的请求更显式,也让浏览器有机会实施预算、权限或策略控制。

但从指纹角度看,只要站点获得架构、完整版本、平台版本和设备型号,这些字段仍可能增加可区分度。RFC 8942 也把隐私与性能影响列为设计约束。开发者应问的不是“能不能拿到”,而是:

  • 当前功能是否真的需要这个字段?
  • 能否用能力检测或用户选择替代?
  • 是否可以只保存粗粒度分类?
  • 原始值保存多久,哪些人员或系统可以访问?
  • 第三方脚本是否也会收到这些提示?

八、服务端解析 UA 的工程建议

1. 不要把 UA 当作权限或身份依据

UA 可以用于展示提示和兼容回退,但不能单独决定登录身份、授权范围、支付信任或安全级别。任何可以由客户端修改的字段都不应成为权限边界。

2. 优先能力检测,而不是浏览器名单

前端需要某个 API 时,应测试该能力是否存在:

if ('share' in navigator) {
  // 提供系统分享能力
} else {
  // 提供复制链接等回退方案
}

相比“如果是 Chrome 145 就启用”,能力检测能更好地处理衍生浏览器、实验功能、企业策略和未来版本。

3. 同时接受传统 UA、Client Hints 与未知状态

在迁移期,服务端可能遇到三类请求:只有传统 UA、同时包含 UA 与 Client Hints、两者都高度缩减。数据模型应允许 unknown,不要为了填满字段而猜测精确系统或型号。

4. 降低日志颗粒度

如果统计只需要“桌面 / 移动、主流浏览器家族、主版本”,就不必长期保存原始 UA 和全部高熵提示。最小化日志既降低隐私风险,也减少分析系统把正常细微差异误当重要维度的机会。

5. 把异常当作信号,不当作判决

“UA 声称 Windows,但某个接口看起来不像 Windows”最多是一项风险特征。企业环境、虚拟化、远程会话、兼容层和辅助技术都可能产生合理异常。将单项矛盾直接等同于欺诈,会制造大量误报。

九、多环境管理中,UA 应该如何配置?

对于跨地区测试、广告预览、账号运营和隐私隔离场景,UA 配置的目标不应是“越新奇越好”,而应是可解释、稳定且与环境相容。

建议按以下顺序检查:

  1. 浏览器版本:UA 主版本应与实际内核能力处于合理范围,不要声明一个内核不可能支持的版本;
  2. 操作系统:UA 平台、Client Hints 平台和 JavaScript 暴露的平台类别应互相相容;
  3. 架构与位数:不要让 UA、Client Hints 和可执行环境出现明显冲突;
  4. 设备形态:移动标记应与触控、视口、像素比和交互方式整体合理;
  5. 区域信息:语言、时区、地理位置和代理出口不必机械一致,但应符合真实业务场景;
  6. 环境稳定性:同一账号或测试身份长期复用同一环境时,避免无理由频繁切换平台和主版本。

PurpleMark(紫纹浏览器)的当前环境转换会把所选操作系统映射为内核 UA 平台,并优先从配置中的 Chrome/CriOS/ 片段提取浏览器版本;没有可用版本时,再按当前内核主版本生成合理回退。这样做的重点不是伪造一条孤立字符串,而是让 UA 配置进入统一的浏览器环境模型。

使用时仍需注意:环境隔离和参数一致性只能降低技术层面的关联与测试偏差,不能保证账号不被关联,也不能替代平台规则、账号资料、支付信息和操作行为管理。相关能力应只用于合法的隐私保护、授权测试与合规业务。

十、常见问题 FAQ

Q1:修改 UA 后,浏览器就真的变成另一个浏览器了吗?

不会。UA 改变的是对外声明的一部分信息,不会自动替换 JavaScript 引擎、渲染管线、网络栈和支持的 Web API。

Q2:网站能读取“真实 UA”吗?

不存在一个所有网站都能绕过浏览器直接读取的硬件级“真实 UA”。但网站可以通过 Client Hints、能力检测和其他指纹信号发现声明与行为不相容,并据此做概率推断。

Q3:UA Reduction 后,网站还能判断 Windows 10 和 Windows 11 吗?

仅靠缩减后的传统 UA 通常不能可靠区分,因为两者可能都显示 Windows NT 10.0。支持 UA Client Hints 的浏览器在站点按需请求后,可能提供更细的平台版本信息;服务端仍应允许缺失和映射差异。

Q4:关闭 JavaScript 就能阻止 UA 暴露吗?

不能完全阻止。HTTP User-Agent 是请求头,发送页面请求时就可能出现,不依赖页面 JavaScript。关闭 JavaScript 会减少部分可采集信号,但也会严重影响现代网站功能。

Q5:Client Hints 会彻底取代 User-Agent 吗?

短期内不应这样假设。传统 UA 仍被大量客户端和服务器用于兼容;UA Client Hints 的支持也并不一致。工程上应把它视为渐进增强:优先使用结构化提示,但始终准备传统 UA 和未知状态的回退。

Q6:随机生成 UA 能提高匿名性吗?

未必。随机 UA 可能让单个字段变化,却同时制造版本、平台、触控和渲染信号之间的矛盾。对长期环境而言,稳定、常见且内部相容的配置通常比高频随机更可解释。

十一、结语

User-Agent 从来不是可靠身份凭证,也不是无关紧要的普通字符串。它处在 Web 兼容、隐私与风控的交界处:对开发者,它是历史包袱沉重的兼容输入;对指纹研究者,它是具有统计信息量的一项属性;对浏览器厂商,它又是需要减少默认暴露的隐私表面。

理解 UA 的关键,可以压缩成三句话:

  • 不要按自然语言直读 UA,里面有大量历史兼容标记;
  • 不要孤立评价 UA,真正的识别能力来自多个信号的组合与时间演化;
  • 不要把 Client Hints 理解成“更多 UA 字段”,它的价值在于结构化、按需和可治理的信息暴露。

当系统设计从“识别浏览器名字”转向“检测需要的能力”,从“尽可能多地采集”转向“只请求必要信息”,UA 才会从脆弱的判断依据,回到它更合适的位置:兼容性线索,而不是身份真相。

参考文献与标准

  1. Peter Eckersley. How Unique Is Your Web Browser?. Privacy Enhancing Technologies Symposium, 2010.
  2. Pierre Laperdrix, Nataliia Bielova, Benoit Baudry, Gildas Avoine. Browser Fingerprinting: A Survey. ACM Transactions on the Web, 2020.
  3. Antoine Vastel, Pierre Laperdrix, Walter Rudametkin, Romain Rouvoy. FP-Scanner: The Privacy Implications of Browser Fingerprint Inconsistencies. USENIX Security Symposium, 2018.
  4. Antoine Vastel, Pierre Laperdrix, Walter Rudametkin, Romain Rouvoy. FP-STALKER: Tracking Browser Fingerprint Evolutions. IEEE Symposium on Security and Privacy, 2018.
  5. IETF. RFC 9110: HTTP Semantics, 2022.
  6. IETF. RFC 8942: HTTP Client Hints, 2021.
  7. WICG. User-Agent Client Hints, Draft Community Group Report.
  8. Chromium. User-Agent Reduction.
  9. Chrome for Developers. Improve user privacy and developer experience with User-Agent Client Hints.