不使用 Cookie 计数
访客计数器只有一项棘手的任务:分辨出两次访问是否不同。如果做不到,一个人把页面刷新十次,看起来就会像十个人访问过,而网站上的数字也就成了虚构。
常见的做法是使用 Cookie。本站没有使用它。下面是本站实际采用的方法,以及为什么这句诚实的话背后其实费了一番功夫。
没人要求过的 Cookie
直到今年之前,每一次对计数器的请求都会启动一个 PHP 会话。这只是一行代码,看起来无伤大雅,但它意味着每一个使用 Stats4U 计数器的网站,其每一位访客都会收到一个会话 Cookie——由我们设置,出现在别人的页面上,而这并非任何一方的本意。
这个会话从未被用来做任何事。只要有人去查看,证据一目了然:存放会话的目录里一个文件都没有。多年来,它一直在别人的网站上设置 Cookie,用来保存从未被写入、也从未被读取的数据。
它已经从计数流程中移除。现在只有在有人创建或重新配置计数器时才会启动会话——那是他们在本站主动做出的操作。
取而代之的方法
访客的区分依靠一个哈希值。参与运算的有五项:
- IP 地址
- 用户代理
- 计数器 ID
- 当天日期
- 一个每天都会变化的密钥
运算得到 16 字节的结果,这才是被存储的内容。它会保留两天,随后删除。IP 地址本身在任何环节都不会被记录下来。
同一个人在同一天两次访问同一个计数器,会得到相同的 16 字节结果,因此第二次会被识别为重复访问。到了第二天,同一个人得到的结果会完全不同,因为日期和密钥都变了。这就是整个机制。
密钥为什么要轮换
这一部分很容易出错,而本站在今年之前也确实做错了。
旧版本使用的是一个永久不变的密钥。这样做仍然能为不同的人生成不同的哈希值,听起来似乎没问题。但这意味着,任何持有这个密钥的人,都可以拿一个可疑的 IP 地址,反推出它在存档中任意一天的哈希值——把一张匿名的 16 字节数值表,还原成一份记录谁访问过什么的档案,而且能一直追溯到数据存在的最早时间。
现在密钥每天都会更换,旧密钥会在两天后删除。一旦删除,这个反推计算任何人都无法再进行——包括运营本站的人在内,而这正是关键所在:一项依赖运营者自觉行为的保护措施,称不上是保护,只是一句承诺。
屏幕分辨率,以及关于「删除」的一课
屏幕分辨率过去是会被收集的。它是一种典型的指纹识别信号,权衡下来并不值得,于是它被从运行在站点页面上的脚本中移除了。
但这样做还不够,原因值得任何为别人的网站开发东西的人了解。这个脚本的缓存有效期是七天,所以改动之后,旧版本仍会在访客的浏览器里继续存活一周。更糟的是,有些网站根本没有链接这个脚本——他们多年前就把脚本的副本粘贴进了自己的页面,而那份副本会永远原样运行,就跟它被粘贴进去的那天一模一样。
于是分辨率数据仍在不断传来。解决办法是让服务器拒绝接收这个值,不管是谁发送的。只在客户端移除数据采集,只能拦住新的客户端。而在服务器端移除,则能立即生效。
自行验证
光是这样说没有多大说服力,所以这里给出具体命令:
- curl -sk -D - -o /dev/null 'https://www.stats4u.net/index.php?action=pic&s4uid=1' | grep -i set-cookie
没有输出,就表示没有设置 Cookie。
最后照例提醒一句:以上说明的是本软件的实际行为。至于这是否满足某地适用的法规要求,应由具备相应资质的人来解答,本文并不是那个答案。
更新(2026 年 9 月 11 日):自 2026 年 8 月 27 日起,脚本又开始在每一个嵌入了它的网站上读取屏幕分辨率、浏览器窗口宽度和像素比。自 2026 年 9 月 11 日起,它只在站点所有者用 data-screen="1" 开启的地方这样做。没有这个属性,当前的脚本三项都不读取,服务器也不再保存由旧版副本发来的这些数值。