首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >字体指纹:字体列表与文本测量如何暴露浏览器环境

字体指纹:字体列表与文本测量如何暴露浏览器环境

原创
作者头像
跨境出海观察员
发布于 2026-11-07 13:37:37
发布于 2026-11-07 13:37:37
310
举报

浏览器指纹有很多信号,字体是最容易被低估的一个。它不像 Canvas 那样需要绘制复杂图形,也不像 WebGL 那样依赖 GPU,但只要页面测量几段文字的宽度,就能推断出操作系统、字体包和渲染环境。

一、字体指纹怎么采集

最常见的做法是准备一组常见字体,用 canvas 的 measureText 测量同一段文本在不同字体下的宽度。如果某个字体不存在,浏览器会回退到默认字体,测出的宽度就会和“存在该字体”时不同。

代码语言:javascript
复制
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const probe = 'mmmmmmmmmmlli';
const fonts = ['Arial', 'Segoe UI', 'PingFang SC', 'Noto Sans CJK SC'];

for (const font of fonts) {
  ctx.font = `16px "${font}", monospace`;
  console.log(font, ctx.measureText(probe).width);
}

除了宽度,还可以用 document.fonts.check('16px Arial') 判断字体是否可用。但 check 只回答“能不能用”,不回答“实际用了哪个字体”;测量宽度更可靠,也更容易组合成特征向量。

如果只想判断某个字体是否存在,可以用 document.fonts.check 做初筛;要区分“存在但被回退”和“不存在”,还是要用多组文本测量。

二、为什么字体能暴露环境

不同操作系统的默认字体不同:Windows 常见 Segoe UI、Microsoft YaHei;macOS 常见 SF Pro、PingFang SC;Linux 常见 DejaVu Sans、Noto Sans。字体版本、字重、hinting 和抗锯齿策略也会影响渲染结果。

平台不需要知道你的全部字体列表,只要几组宽度组合,就能把环境分到某个“字体簇”。如果 UA 写着 Windows,但测不到 Segoe UI,反而出现一堆 Linux 常见字体,这就是一个明显的矛盾。

字体还有一个特点:稳定。用户很少每天装删字体,所以字体指纹在几个月内变化不大。对平台来说,稳定信号比随机信号更有价值。

字体指纹的熵不一定比 Canvas 高,但稳定性通常更好;平台通常把它和 UA、platform、时区、语言一起用,而不是单独依赖字体。因此,字体更适合做“辅助证据”:单独看不一定能定位设备,但和 UA、platform、时区组合后,能快速排除明显矛盾。

CSS 的 font-family 是一个回退链:Arial 不存在时,浏览器会依次尝试后面的字体,最后落到系统默认。测量结果反映的是最终使用的字体,而不是声明里的第一个名字。

CSS Font Loading API 的 document.fonts.ready 可以等待自定义字体加载完成;如果测量发生在字体加载前,结果会落到回退字体,导致同一环境前后不一致。

三、常见误区

误区一:改了 UA 就等于改了系统。 UA 只是字符串,字体、Canvas、WebGL 不会跟着变。UA 写 Windows、字体却是 Linux 组合,比不改 UA 更可疑。

误区二:装一套“指纹浏览器字体包”就万事大吉。 字体包要和操作系统、语言、UA 匹配;只堆字体数量,不处理回退关系,反而会制造新的矛盾。

误区三:字体指纹只影响 Canvas。 字体还会影响页面布局、文本换行、按钮尺寸,甚至影响截图和 OCR 的结果;它不只是绘图参数。

四、怎么检查一致性

第一,确认系统字体与 UA 匹配。Windows 环境至少要有 Segoe UI、Arial、Microsoft YaHei;macOS 环境要有 SF Pro、PingFang SC;Linux 环境要有 DejaVu、Noto。

第二,检查语言与字体。en-US 环境不需要大量中文字体;zh-CN 环境缺少中文字体会导致回退,反而暴露环境。

第三,用同一段文本做交叉测量。不要只看一个字体,至少测 5—10 个常见字体,观察宽度分布是否符合目标系统。

第四,注意浏览器隐私限制。部分浏览器会限制字体枚举,document.fonts.check 的结果可能被隐私策略影响;测量结果要结合浏览器版本解释,不能一概而论。

第五,用 DevTools 交叉验证。Elements → Computed → Rendered Fonts 会显示实际使用的字体,可以和测量结果对照;如果声明的是 Arial,实际渲染的却是 Noto Sans,说明回退已经发生。在 DevTools 里禁用某个字体后重新测量,可以看到回退链的变化;这比只记一个宽度值更能说明问题。

五、总结

字体指纹不是“装了什么字体”这么简单,它反映的是操作系统、字体包、语言和渲染栈的组合。对多账号环境来说,字体列表和 UA、时区、语言一样,需要保持一致;只改 UA 不改字体,等于把矛盾留在页面里。

检查字体指纹不需要复杂工具,一段 canvas 测量代码就够。关键是理解:平台看的是组合,不是单个字体。

不要为了“看起来更像某个系统”而盲目安装字体包。字体、语言、UA、时区必须一起调整;单独堆字体,反而容易制造新的矛盾。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、字体指纹怎么采集
  • 二、为什么字体能暴露环境
  • 三、常见误区
  • 四、怎么检查一致性
  • 五、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档