浏览器时区泄露怎么自查:Intl、Accept-Language 与系统设置对照
浏览器时区泄露,指的是网页脚本直接读取你操作系统的时区设置,不需要弹窗授权,也不受代理影响。语言同理:浏览器每发一个请求都会带上 Accept-Language 头,脚本还能读 navigator.languages。所以出口 IP 换到哪里都一样,Asia/Shanghai 和 zh-CN 还是会原样交给网站。
这篇文章只回答一个问题:这些值具体从哪里来、由哪个设置决定、怎么自己查清楚。目的是隐私自查,帮你知道用代理时还有哪些系统信息会被网站读到。文章不讨论如何伪装环境去通过任何平台的风控,使用各类服务时请遵守其服务条款和当地法规。
如果你想先了解时区、语言、字体和 IP 对不上分别意味着什么,可以先读浏览器指纹与环境检测:时区、语言、字体和 IP 对不上,各自暴露了什么。本文更偏操作:给命令、给设置位置。
网页从哪几个地方读到时区和语言?
一共四个直接来源,外加一个间接来源。
| 来源 | 读取方式 | 返回值示例 | 需要 JavaScript 吗 |
|---|---|---|---|
| IANA 时区名 | Intl.DateTimeFormat().resolvedOptions().timeZone | Asia/Shanghai | 需要 |
| UTC 偏移 | new Date().getTimezoneOffset() | -480 | 需要 |
| 语言偏好列表 | navigator.language、navigator.languages | zh-CN、["zh-CN","zh","en"] | 需要 |
| HTTP 请求头 | Accept-Language | zh-CN,zh;q=0.9,en;q=0.8 | 不需要,服务器直接收到 |
| 字体(间接) | Canvas 或 CSS 测量文字宽度,判断某字体是否存在 | 是否装有常见中文字体 | 需要 |
几个容易误解的地方:
getTimezoneOffset()的符号是反的。它返回“UTC 减本地时间”的分钟数,东八区得到-480,不是480。它只给偏移,不给地区,同一个偏移下有很多时区。- IANA 时区名的信息量更大。
Asia/Shanghai和Asia/Hong_Kong、Asia/Taipei偏移相同,名字却直接对应地区。 Accept-Language是表中唯一不靠脚本的来源。关掉 JavaScript 也挡不住,服务器在第一个请求里就能看到。q=0.9这类权重表示偏好排序。- 字体只是旁证。装了中文字体不代表系统语言是中文,很多英文系统也会装。它的作用是和其他几项一起看。
在自己电脑上怎么读到这些值?
打开任意网页,按 F12 进入控制台(Console),粘贴下面这段:
const r = Intl.DateTimeFormat().resolvedOptions();
console.table({
timeZone: r.timeZone,
locale: r.locale,
offsetMinutes: new Date().getTimezoneOffset(),
language: navigator.language,
languages: navigator.languages.join(", "),
dateString: new Date().toString(),
});
dateString 这一行通常带有本地化的时区名称,比如括号里的“中国标准时间”,这同时暴露了时区和系统语言。
Accept-Language 要在网络面板里看:DevTools 切到 Network,刷新页面,点第一个文档请求,在 Request Headers 里找 accept-language。
这些值分别由哪里决定?
大致规律:时区跟操作系统走,语言在不同浏览器里来源不同。
时区
| 环境 | 决定时区的设置 | 命令行查看 |
|---|---|---|
| Windows | 设置 → 时间和语言 → 日期和时间;开启“自动设置时区”时会参考定位服务 | tzutil /g 或 PowerShell Get-TimeZone |
| macOS | 系统设置 → 通用 → 日期与时间;“自动设置时区”同样依赖定位 | readlink /etc/localtime |
| Linux | /etc/localtime 或 timedatectl 设置;启动进程时的 TZ 环境变量会覆盖 | timedatectl、echo $TZ |
| Chrome / Edge | 跟随系统,没有独立的时区设置 | 用上面的控制台代码 |
| Firefox | 默认跟随系统;开启 privacy.resistFingerprinting 后改为报告 UTC 零偏移 | 同上 |
| Safari | 跟随系统 | 同上 |
“自动设置时区”这一项会让时区跟着设备的物理位置变,而不是跟着网络出口变。所以笔记本带出门,时区可能自动改了;挂上代理,时区不会动。
Windows 的 tzutil /g 返回的是 Windows 自己的时区 ID(例如 China Standard Time),浏览器内部会换算成 IANA 名称,两者写法不同属于正常现象。
语言
| 环境 | navigator.languages 和 Accept-Language 来自 | 在哪里改 |
|---|---|---|
| Chrome / Edge | 浏览器自己的“首选语言”列表,首次安装时按系统语言生成 | 设置 → 语言 → 首选语言,可以拖动排序 |
| Firefox | 浏览器自己的网页语言列表 | 设置 → 常规 → 语言 → “选择网页显示语言” |
| Safari | macOS 的首选语言列表 | 系统设置 → 通用 → 语言与地区 |
| Windows 系统 | 设置 → 时间和语言 → 语言和区域 → 首选语言 | PowerShell Get-WinUserLanguageList、Get-Culture |
| macOS 系统 | 系统设置 → 通用 → 语言与地区 | defaults read -g AppleLanguages、defaults read -g AppleLocale |
| Linux | LANG、LC_* 环境变量,以及桌面环境的区域设置 | locale |
这里有个常见情况:在 Chrome 里改了首选语言,系统语言没改,于是 navigator.languages 变了,但 new Date().toString() 里的时区名称、数字和日期格式可能仍是中文习惯。语言相关的信号不止一处,改一处不等于全改。
字体
字体列表来自本机安装的字体文件。Linux 上可以用 fc-list :lang=zh family 看装了哪些中文字体;Windows 在 C:\Windows\Fonts,macOS 在“字体册”里。网站通常不会拿到完整列表,而是逐个测试一批常见字体是否存在。字体指纹的更多原理可以看浏览器指纹是什么:网站不靠 Cookie 能认出你的 20 多项特征与自查方法。
用 cdnping /ip 做一次完整自查
控制台只能看到浏览器这一侧。要和出口 IP 放在一起对照,用 IP 与环境检测 更方便:它会显示出口 IP 的地理定位(11 个地理库投票并给出置信度),同时检测时区、语言和字体。指纹在本地计算,不上传。
按下面的顺序做:
- 在平时的状态下打开 /ip,不要特意改任何设置。记下出口 IP 的国家和城市、置信度,以及时区、语言、字体三项的结果。
- 核对出口 IP 定位是否可信。如果各地理库说法分歧很大,先别急着下结论,地理库本身就会不准,原因见为什么 11 个 IP 库给出不同位置。
- 对照时区与 IP 所在地。时区名对应的地区和 IP 定位相同,说明两者一致;不同,说明网站能看出“设备在一个地方,网络出口在另一个地方”。
- 对照语言列表。看第一语言是什么、列表里有几种语言。列表越长、组合越少见,越容易成为区分你的特征。
- 看同一页的大陆分流和多出口结果。如果国内站点看到的是另一个 IP,那就不只是时区语言的问题了,可以读国内网站如何看到你的真实 IP:大陆分流检测的原理与三种结果和分流原理。
- 需要分享结果时,打开隐藏 IP 的选项再生成带水印的结果图,不要直接截全屏。
每个检测项具体怎么解读,可以参考浏览器环境检测怎么看:13 项检测逐项解读。
时区和 IP 对不上,一定是坏事吗?
不一定。下面这些都是正常场景:
- 在国外出差,没开“自动设置时区”,系统还停在国内时区。
- 公司网络统一从某个海外出口出去,员工时区都是本地。
- 移动网络或企业专线的 IP 被地理库定位到了别的城市。
从隐私角度看,问题不在于“对不上”本身,而在于你是否清楚自己暴露了什么。如果你用代理的初衷是不让网站知道你身在何处,那么时区和语言仍会透露你所在的大致地区。
反过来,把时区、语言改得和出口 IP 一致,也不是本文建议的做法。一方面这会影响日常使用(日程、文件时间、网页显示语言都会跟着变),另一方面,一些服务会把浏览器环境信号用于安全判断,具体规则以各平台条款为准,请遵守服务条款和当地法规。
想少暴露一些,有哪些合理的做法?
只列对日常使用影响小、出于隐私目的的做法:
| 做法 | 效果 | 代价 |
|---|---|---|
| 精简浏览器语言列表,只保留真正需要的一两种 | 降低语言列表的独特性 | 少数网站的多语言回退可能不如以前 |
| 关闭系统“自动设置时区”,手动设定常用时区 | 避免时区随物理位置变化暴露行程 | 出行时需要手动调整 |
Firefox 开启 privacy.resistFingerprinting | 时区改报 UTC 零偏移,还会降低其他指纹项的精度 | 网页上的时间可能显示错误,部分站点行为异常 |
| 用 Tor Browser 等统一指纹的浏览器处理敏感浏览 | 大量用户报告相同的值 | 速度慢,部分站点会拦截或频繁要求验证 |
| 一并检查 WebRTC 和 DNS | 避免 IP 本身从别的通道泄漏 | 需要逐个浏览器设置 |
最后一项通常比时区更要紧:时区只能暴露大致地区,WebRTC 泄漏可能直接暴露真实 IP。设置方法见WebRTC 泄漏怎么关:Chrome、Firefox、Safari 设置,原理见 DNS 泄漏与 WebRTC 泄漏。
让浏览器保持“普通”比让它“随机”更有用:东拼西凑的设置组合本身就罕见,反而更容易被区分出来。
开发者测试多语言站点时怎么模拟时区?
如果你是在测自己网站的国际化逻辑,不需要改系统设置。Chrome DevTools 里打开 Sensors 面板(命令菜单输入 “Show Sensors”),可以为当前标签页覆盖时区 ID 和区域设置,关掉 DevTools 即恢复。Linux 和 macOS 上也可以用 TZ=America/New_York 这样的环境变量启动一个单独的浏览器实例做测试。
这类方法只用于开发调试。测完后回到正常浏览状态,再用 /ip 确认一遍设置没有残留。