时区、语言和 IP 不一致会被识别吗?怎么保持一致?
会。而且在网站能用的所有识别手段里,这一类最便宜——不用采集显卡、不用画图算哈希,只要把你请求里必然带着的 IP 拿去查一次归属地,再用一行脚本读一下浏览器自己报的时区和语言,两边对一下就有结论。正因为便宜,它往往是风控流程里最先跑的一步。反过来说这也是最好修的一类问题:把时区、语言、地理位置三项都交给「跟随 IP 自动匹配」,配好之后不要再手动动它们,绝大多数不一致就不会发生。
为什么这三项特别容易被抓:网站手上有两套互不相干的信息源
指纹里大部分项目只有一个来源。浏览器说自己有 8 个 CPU 核心,网站就只能听它说,没有第二个渠道可以核对。但国家、时区、语言这三样不一样,它们有两条互相独立的路径都能拿到,于是天然具备了「对账」的条件。
第一条是服务端侧。你的每个请求都必须带一个能回包的公网 IP,网站把这个 IP 丢进 IP 归属地库,就能查出国家、省州、城市、运营商和 ASN(自治域编号,可以理解成这段 IP 登记在哪家网络运营商名下),顺带也就知道了这个地方应该在哪个时区、当地人一般用什么语言。这条路径你控制不了:IP 是通信的前提,藏不掉也伪造不了。
第二条是客户端侧。浏览器会主动把这些信息交给页面:Intl.DateTimeFormat().resolvedOptions().timeZone 返回一个 IANA 时区名(形如 Asia/Shanghai、America/Los_Angeles),new Date().getTimezoneOffset() 返回一个以分钟计的偏移量,navigator.language 和 navigator.languages 给出语言偏好,而每一个 HTTP 请求头里还额外带着一份 Accept-Language。这些值是可以改的,也正是指纹浏览器在处理的东西。
两条路径合起来,网站要做的只是三次比较:IP 归属的国家和时区指向的国家是不是同一个;时区名和偏移量本身对不对得上;语言列表的第一项和 IP 国家的常用语言是不是一回事。三次比较全部通过,这一层就没什么可说的;有一次不通过,就是一条现成的线索。
能互相打脸的七个信号
| 信号 | 来自哪一侧 | 网站拿它做什么 |
|---|---|---|
| 请求来源 IP | 服务端观测 | 查归属国家、城市、运营商与 ASN |
| Accept-Language 请求头 | 客户端上报(HTTP 层) | 看语言偏好顺序,与 IP 国家对照 |
| navigator.languages | 客户端上报(JS 层) | 与上一行必须一致,改一处漏一处最常见 |
| Intl 时区名 | 客户端上报(JS 层) | 直接拿到一个具体地区名 |
| getTimezoneOffset 偏移 | 客户端上报(JS 层) | 与时区名交叉验证,也用来查夏令时 |
| 本机时钟 | 客户端上报(JS 层) | 与服务器时间比,差太多本身就是特征 |
| Geolocation 坐标 | 客户端授权后上报 | 与 IP 位置算距离 |
这七行里最值得单独记住的是第二和第三行。Accept-Language 是 HTTP 请求头,随每个请求在网络层发出;navigator.languages 是 JS 里读到的数组,属于浏览器内部状态。两者描述同一件事,但走的是两套不同机制,很多手工改语言的做法只改了其中一个。网站把两边取出来比一下字符串就能发现问题——这属于自我矛盾,它连你真实在哪都不需要知道,光看你自己交上来的两份材料就对不上。
时区不是一个数字,是三样必须自洽的东西
很多人以为设时区就是挑一个 UTC+8 或 UTC-8。实际上页面能读到三层信息:一是 IANA 时区名,形如 Asia/Shanghai,这是个地理概念;二是当前偏移量,以分钟计;三是这个时区当下是否处在夏令时。三者必须彼此吻合。常见破绽有两种。一种是只改了偏移量、时区名还是原来的,于是页面看到一台自称在上海、却比 UTC 慢七小时的电脑。另一种是时区名对了但夏令时没跟上:美国西部 3 月到 11 月的偏移是 −7 小时,只有冬季才是 −8 小时,如果全年固定 −8,夏天就会和当地实际时间差整一小时。这两种都属于硬矛盾,比「IP 在美国、时区在中国」更容易被程序化判定,因为它连解释空间都没有。
常见的不一致组合,以及网站看到的样子
| 组合 | 网站看到的样子 | 严重程度 |
|---|---|---|
| 美国 IP + 时区 Asia/Shanghai + 语言只有 zh-CN | 一台在东八区、只会中文的电脑,从美国出口访问 | 强,最典型 |
| 时区名与偏移量对不上 | 自己交的两份材料互相冲突 | 硬矛盾,必须修 |
| Accept-Language 与 navigator.languages 不同 | HTTP 层与 JS 层各说各话 | 硬矛盾,必须修 |
| 换了代理国家,时区语言没跟着换 | 上次登录在德国,这次 IP 在美国、时区还是柏林 | 强 |
| 英国 IP + America/New_York | 同为英语区,国家层面仍然对不上 | 中到强 |
| 夏令时没处理 | 与当地实际时间差一小时 | 中,程序化容易发现 |
| 地理位置直接允许,坐标离 IP 几千公里 | 声称在洛杉矶、坐标却在广州 | 强,且是自己主动交出去的 |
| IP 城市与时区城市不同,但同属一个时区 | 在同一时区内跨城市 | 弱,现实常见 |
| 美国 IP + 语言列表含中文但不排第一 | 一个在美国生活的中文用户 | 弱,可以接受 |
看这张表要抓住一条主线:网站真正在意的不是「差异」,而是「矛盾」。差异在现实里到处都有——出差的人、留学的人、用公司跨国网络的人,时区和 IP 对不上是常态。矛盾不一样,矛盾是同一台电脑对同一个问题给出了两个互相排斥的答案,现实中不存在这种机器。所以修一致性的优先顺序永远是先清掉矛盾,再去缩小差异。
「跟随 IP 自动匹配」到底做了什么
这个开关不神秘,它做的就是把前面那套推理反着跑一遍:既然网站会从 IP 推出应该有的时区和语言,那就干脆按同一套逻辑先把值填好。大致流程是这样的。
- 在窗口里把代理填好,用客户端自带的检测功能确认能连通,并看到它报出来的出口 IP 与归属地。
- 客户端拿这个出口 IP 去查归属地库,得到国家、城市与大致经纬度。
- 由归属地反推出该地区的 IANA 时区名,写进窗口的时区配置。
- 由归属国家反推出一份合理的语言列表,写进 Accept-Language 与 navigator.languages。
- 地理位置按同一个归属地给一组坐标,或者保持「询问」,等页面申请时再给。
- 窗口启动后浏览器读到的就是这一套值,与出口 IP 同源,三次比对自然都能对上。
自动匹配也有它管不到的地方,两点要注意。第一是归属地库本身可能不准:新分配的 IP 段、跨境经营的 ASN、转售过的地址,在不同归属地库里可能被标到不同城市甚至不同国家;库错了,跟着它匹配出来的时区语言也会一起错。第二是「国家的官方语言」不等于「当地人浏览器里的语言」。加拿大英法双语,瑞士和比利时更复杂,印度的实际网络使用者大量以英文为主,新加坡也是英文优先。自动匹配给的是一个统计上的合理默认值,碰到这些国家值得自己再看一眼。
语言列表怎么填才自然
语言不是一个值,是一个带优先顺序的列表。Accept-Language 的完整形态类似 en-US,en;q=0.9,q 是权重,越靠前、权重越高表示越优先。所以这里有两个维度:都有哪些语言,以及谁排第一。绝大多数真实用户的第一项就是所在地区的主语言,后面跟一个不带地区的兜底项。
| 目标市场 | 一个合理的语言列表 | 说明 |
|---|---|---|
| 美国 | en-US, en | 最常见形态:第一项带地区,第二项兜底 |
| 英国 | en-GB, en | 用 en-GB,不要拿 en-US 顶替 |
| 德国 | de-DE, de, en | 非英语国家通常会在后面带一个 en |
| 日本 | ja-JP, ja, en | 同上 |
| 加拿大 | en-CA, en, fr-CA | 双语国家,法语项排在后面更常见 |
| 巴西 | pt-BR, pt, en | 用 pt-BR,不是 pt-PT |
华人卖家常纠结一件事:语言列表里到底能不能留中文。可以留,但不要排第一。一个在美国生活的华人,浏览器第一项是 en-US、后面跟着 zh-CN,这是很自然的组合。反过来第一项就是 zh-CN、连 en 都没有,再配一个美国出口 IP,就成了一个只会中文的美国住户,这个人群要小得多。另外注意客户端界面语言和窗口向网站上报的语言是两件事,前者是你自己看的,后者才进指纹;配好之后窗口里的网页会显示成外文,这是正常的。
手动兜底:四步确认这一套真的对上了
- 确认出口 IP。开窗口,看一个能显示来源 IP 与归属地的页面,记下它报出来的国家、城市、运营商。这一步不过就别往下走,先去修代理。
- 确认时区的两层。看页面读到的 IANA 时区名是否落在上一步那个国家,再看偏移量与该时区当季的真实偏移是否一致(记得算夏令时)。名字和偏移只要一处不对,就是硬矛盾。
- 确认语言的两处。把 HTTP 请求头里的 Accept-Language 和 JS 里的 navigator.languages 分别看一眼,两者必须相同,且第一项与 IP 国家相符。
- 顺手看一眼本机时钟。系统时间差几分钟无所谓,差几小时就会和时区配置一起构成矛盾——这一项归操作系统管,改浏览器没用。
具体用哪些检测站、每个站的指标分别怎么读、结果怎么判,属于《怎么验证指纹环境是否正常?用哪些检测网站》,本篇不展开站点清单。
不一致到什么程度才算问题
- 硬矛盾:必须修。特征是不需要任何外部参照,只看你自己给出的几份材料就能发现冲突——时区名与偏移不符、
Accept-Language与navigator.languages不同、夏令时没处理。这一类没有合理解释空间。 - 强不一致:应该修。IP 国家与时区国家不同、换了代理国家但时区语言没跟着换、主动交出一个离 IP 几千公里的坐标。现实里当然有人在国外还用着家乡时区,但这个组合在目标平台的正常用户里占比很低。
- 弱不一致:可以接受。同一时区内的城市不一致、语言列表含非当地语言但不排第一、IP 显示的运营商不是当地最主流的那家。出差、留学、移民、跨国办公的人一直都有,把每一项都修到完美反而没必要。
- 还有一类容易被忽略:全都读不到。把时区接口屏蔽、语言列表清空,页面拿到的不是一个普通值,而是一片空白。真实用户几乎不会这么干,这比轻微不一致更显眼。
这些内容不在本篇范围内
可调指纹参数的完整清单与每一类的默认策略,看《比特浏览器能改哪些浏览器指纹?完整参数清单》;Canvas、WebGL、AudioContext 这类硬件指纹怎么被采集,看《Canvas、WebGL、AudioContext 指纹是怎么被采集的?噪音模式怎么选》;WebRTC 会不会把真实 IP 漏出去,看《WebRTC 会泄漏真实 IP 吗?三种模式怎么设》;住宅 IP 和机房 IP 怎么挑、纯净度怎么查,看《住宅 IP、机房 IP、移动 IP 怎么选?IP 纯净度怎么看》;浏览器根本管不到的那些关联因素,看《用了指纹浏览器就一定不会被关联吗?》。本篇只回答「三者怎么交叉校验、怎么保持一致」这一个问题。
