你在某家商店的网站上看过一次登山靴。现在你打开的每个网站,都想卖你登山靴。最直接的推断是:网站能读取你的浏览记录,还会四处转卖。其实不能。在当前的浏览器上,没有任何网站能读到你访问过的站点清单,可你照样被追踪。
本页上的小工具会向你自己的浏览器询问:它愿意让页面知道你去过哪里?答案几乎是什么也不给,而且是有意为之。
:visited 链接,自 2010 年起已被分阶段堵死。页面现在还能读到的内容很少:你来自哪个站点,后退按钮有几步可退,以及它自己留下的关于你的记录。其余部分,则是由出现在许多站点上的追踪器,以及承载你流量的网络拼凑出来的。没有任何 API 会交出你的浏览记录
看看 window.history 给脚本提供了什么:back()、forward()、go()、pushState()、replaceState()、state、scrollRestoration 和一个 length。其中没有任何一项会返回地址。history.length 统计的是当前标签页的条目数,在 Chrome 和 Firefox 中上限是 50(Safari 保留 100 条),所以它几乎说明不了你浏览过多少内容。
较新的 Navigation API,即 navigation.entries(),确实会返回地址,但只限当前标签页中与该页面同源的条目,而且只限其中连续不断的那一段。页面读到的是它自己的轨迹,看不到别人的。我在 Chromium 156 上做了测试:从另一个源点击链接来到本页之后,history.length 显示为 2,而 navigation.entries() 只列出了一条,就是当前页面。我没有测试 Firefox 和 Safari。
:visited 把戏,以及它是怎么死掉的
多年来一直有一道后门。浏览器会把访问过的链接涂成另一种颜色,而页面可以询问某个链接最终是什么颜色。于是脚本做一个隐形的链接,指向某家银行的登录页,读出它的计算后颜色,就知道你有没有去过。Mozilla 给出的速度是每分钟数十万条链接,没有任何提示,你也毫无察觉。
2010 年 3 月,Mozilla 宣布了修复方案:getComputedStyle 会表现得好像所有链接都没访问过,而访问过的链接只能用少数几个颜色属性来设置样式。如今所有主流引擎都是这么做的。小工具的第一行演示的就是这件事。它询问的是一个指向你此刻正在读的这个页面的链接。按定义你一定访问过它,浏览器却回答“没有”。
撒一个关于颜色的谎,只能堵住直接的路。研究人员不断发现旁路,比如 Paul Stone 在 2013 年提出的攻击,它测量访问过的链接重绘要花多长时间,而每一种旁路都需要单独打补丁。Chrome 的应对方案是修改访问记录的存放位置,在桌面版和安卓版上自 136 版起可用。访问过的链接列表不再是一张表。每个条目都用三个键来存储:链接地址、你当时所在的顶级站点,以及显示这个链接的框架。blog.example 上的页面去查那家银行,现在查的是另一个键,不是你访问银行时存下的那个,于是什么也查不到。
bank.example/login访问时所在页面 bank.examplenews.example/story访问时所在页面 某个搜索页blog.example/post访问时所在页面 blog.example
bank.example/login已访问:泄露了news.example/story已访问:泄露了blog.example/post已访问(它本来就知道) 它自己的页面
一个站点自己的页面,无论你最初是在哪里打开的,仍然会显示为已访问,你从该站点点出去的链接也一样。这不会泄露任何新信息,因为该站点本来就知道这两件事。就我能查证的范围而言,Firefox 和 Safari 没有类似的分区机制,iOS 上的 Chrome 也没有,因为它运行在 WebKit 上。即便如此,2010 年定下的规则也并非滴水不漏:Apple 在 2026 年 7 月发布的 Safari 26.6 说明里,修复了一个 WebKit 漏洞,该漏洞会让网站得知你是否访问过某个链接。
网站能看到你浏览的哪些内容?
引荐来源(referrer)。如果你是从搜索结果点进来的,页面可能会得知是哪个站点把你送来的。自 Chrome 85 和 Firefox 87 起,跨源跳转的默认做法是只发送源,也就是 https://www.google.com/,而不带你的搜索词,除非发送方站点设置了自己的策略。Safari 也会裁剪跨站的引荐来源。在同一次 Chromium 156 测试中,我来的那个页面有很长的路径,而 document.referrer 只返回了它的源。如果你是手动输入地址或者用书签进来的,它就是空的。这也说明了为什么你点进去的站点看不到你搜了什么:你的搜索记录存放在搜索引擎和你的账号里,而不在这个页面里。
它自己的记录。这是最大的一块,也最平淡无奇。一个站点在你上周二访问时设了 cookie,这周二就能认出你。这是一个站点的历史,而不是整个网络的历史,你访问过的每个站点都保存着一份关于你的记录。站点所有者在分析工具里看到的是它自己的访客,包括页面地址、IP 地址和引荐来源,而这个视野止步于站点的边界。
边缘上的几处泄露。跨站的小把戏有时能判断出你是否在别处登录过:加载一个只有登录用户才能用的东西,再测量会发生什么。XS-Leaks wiki 收录了这一类手法。它每次只告诉页面关于一个站点的一个比特,有些通道会被堵上,新的又会冒出来。其中没有任何东西像是一份清单。
追踪器照样能拼出你的浏览记录
广告大多是因为页面上还有谁才会跟着你。广告网络的脚本既出现在鞋店里,也出现在新闻网站上。只要它能在两处都认出你,它手里就有了一份浏览记录,是一个站点一个站点拼出来的,根本不需要你浏览器的历史记录帮忙。FTC 有一篇通俗易懂的网站和应用如何收集这些信息的概述。
Safari 直接屏蔽第三方 cookie,Firefox 按站点对它们做分区。截至 2026 年 11 月,Chrome 默认仍然允许第三方 cookie。cookie 只是认出你的方式之一。在大多数浏览器中,canvas 指纹在每个站点上都可能保持不变,而且不需要存储任何东西,所以清除浏览记录对它毫无作用。
追踪器的脚本也运行在它所在的页面内部,所以它能读到该页面的地址和标题,而不只是记下你来过。其余的内容,请看我们另一篇讲页面在你访问期间能观察到什么的文章。
还有谁能看到你的浏览记录
把页面从画面里拿掉,看看你和某个站点之间这条路径上的其他所有人。他们大多只能看到一部分。同步的浏览器账号是个例外。
- 看得到
- 看到一部分
- 看不到
你的 ISP,或者酒店、办公室里运营 Wi-Fi 的人,看不到 HTTPS 站点的页面地址。但他们通常仍能看到域名,因为 DNS 查询和 TLS 连接的开头都会点出站点的名字。加密 DNS 和 Encrypted Client Hello 在部分站点上可以把这一点藏起来,但服务器的 IP 地址依然可见。VPN 不会抹掉这一部分。它把其中大部分交给了 VPN 公司,而你的 ISP 只知道一件事:你在用 VPN。网站是怎么识别出这一点的,我们在 VPN 检测里讲过。
人们最容易忘掉的一行,是自己的浏览器账号。如果开启了历史记录同步,你打开过的地址的完整清单可能就放在厂商的服务器上。在 Chrome 中,除非你设置了同步密码(passphrase),否则 Google 可以读取同步的历史记录;设置之后,只有你在地址栏里输入过的地址才会同步。Firefox Sync 和 iCloud 会对历史记录加密,所以这两家厂商读不到。
无痕模式、清除历史记录或者换成手机,有用吗?
无痕浏览能让你自己的浏览器不再保存这份清单,并让你以空白的 cookie 开始。但站点、你的 ISP 和 Wi-Fi 的所有者仍然能看到这次访问,而且在大多数浏览器里,指纹仍然能认出你。Safari、隐私窗口中的 Firefox、Brave 和 Tor 会加入噪声或做统一化处理,让这件事变难。清除历史记录会抹掉你浏览器保存的那份清单,连同同步的副本一起,但抹不掉站点、追踪器或你的 ISP 已经掌握的东西。账号活动记录,比如 Google 的“我的活动”,会一直保留它自己的一份,直到你在那里删除。手机也是同样的逻辑:页面拿到的还是那几项读数,真正重要的历史存放在你的账号里或网络上,而不在浏览器里。所以,如果担心的是伴侣或家长,要查两个地方:你们双方都能打开的账号,包括它的同步和活动记录,以及流量所经过的网络。
实际该怎么做
- 检查小工具的第一行。它应该显示“已封堵”。如果显示“会泄露”,说明你的浏览器比 2010 年的修复还旧,或者缺了某个补丁。请更新它,Safari 用户要确保版本在 26.6 或更高。
- 检查你同步了什么。打开浏览器的同步设置,决定历史记录是否需要放进账号里。在 Chrome 中,设置同步密码能让 Google 读不到它。Firefox Sync 和 iCloud 默认就会加密历史记录。
- 清除历史记录挡不住追踪。它会抹掉你浏览器保存的那份清单,连同同步的副本,但不会碰 cookie 和站点数据,也够不到站点、追踪器或你的 ISP 已经掌握的东西。清除 cookie 能切断追踪中依靠 cookie 的那一半,而在大多数浏览器里,指纹那一半两种清除都躲得过去。
- 有意识地把身份分开。追踪器靠关联起作用,所以任何不该被关联的东西,都需要有自己的 cookie、存储和指纹。如果你要以这种方式运行多个账号,Incogniton 会给每个配置文件各配一套,这样同时出现在两个站点上的追踪器,看到的是两个陌生人。前提是你从不同的配置文件打开每个站点,并通过代理给每个配置文件分配各自的 IP 地址。
小工具检查的是页面能读到什么。完整的浏览器扫描检查的是页面能从那些单看毫无害处的属性里推断出你的什么:指纹哈希、围绕你 IP 地址的泄露,以及你的浏览器讲的是不是同一个自洽的故事。