Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

从 UV 统计问题开扯各种 Cookie

  设置 Cookie 本来是一件很容易的事,但最近踩到了个深坑!通常我们都在服务器上种 SessionID。服务器判断请求不带 SessionID 时就会为其生成一个,但服务器程序生成的 SessionID 并不是实时写入客户端的,这个期间的网络延迟会造成 SessionID 统计错误的问题。
  当一个首次访客连续打开多个页面时,这些页面请求都会被以无 Cookie 的状态被发送到服务器,服务器会傻乎乎地将这些请求视为 UV。如果只是这样那倒没什么,但这还没完。服务器会对每个无 Cookie 请求创建 Session,并设置 SessionID。由于网络的缘故,客户端接收响应的顺序是无法确定的。而 SessionID 以 Cookie 的形式写入客户端浏览器时,后面的会覆盖掉前面的。所以无论是服务器端还是客户端都无法确定到底是哪个 SessionID 被留下了。服务器端无法确定很容易理解吧?因为响应了一堆请求,不知道哪个是客户端最后收到的。而客户端无法确定是因为如果客户端的某个请求先完成,页面就会认为当前 SessionID 是正确的,并将这个 Cookie 用于其它 API 请求的发起。但实际上后面的请求完成后就把这个 SessionID 覆盖了,于是就造成各种不同步的问题。
  其实这个问题并不影响程序正常使用。因为根据目前的统计数据,首次访客由于手抽点开多个页面的概念不足 5%,会因为 SessionID 不同步造成错误的概率就几乎是可以忽略不计了,我的纠结点在另一个方面。因为这种情况会生成一些僵尸 Session,如果有一个基于 Session 的数量来统计 UV 的程序,那么这些僵尸 Session 也会被算入,于是统计结果就会出现跳出率虚高的情况。
  大家也许会有个疑问「基于 Session 的数量来统计 UV 的程序」是什么奇葩的存在?实际上目前大部分统计程序都是如此实现的。比如目前最流行的日志打点方案是在某个静态服务器上放个空图片,然后页面去 GET 这个图片资源,并在 GET 参数中带上数据,最后再分析 HTTP 日志来统计 UV、PV 等信息。这个方案就会掉进 Cookie 的这个坑中。所以一个完整的统计程序光有日志打点方案是不够的
  目前网络上的资料中大多数都将 Cookie 分为第一方和第三方,但我觉得这个分法不太好。这里重新定义一下这个概念,我将 Cookie 分为第一方、第二方、第三方。
  • 第一方 Cookie 是浏览器上通过 JavaScript 直接种下的 Cookie
  • 第二方 Cookie 是页面所在的 HTTP 服务器种下的 Cookie
  • 第三方 Cookie 是页面加载后前端程序请求其它资源种下的 Cookie
  第一方 Cookie 是最准确的,因为即使用户同时打开两个页面,在第一个页面写入 Cookie 后第二个页面的程序可以立即读取到,不会产生因网络延迟造成的 Cookie 不同步的问题。但第一方 Cookie 是 JavaScript 可读写的,存在一定的安全性问题,于是第二方 Cookie 就登场了。虽然第二方 Cookie 不如第一方准确,但它可以设置成 HTTP Only 的,一些机密信息可以考虑时候第二方 Cookie 存储。那么问题又来了,无论是第一方还是第二方,它们都无法跨主域名通信。所以我们可以用一个单独的域名来提供第三方 Cookie 在其他所有域上共享一些跨域数据。
  UV 统计的依据应该使用第一方 Cookie,如果产品存在跨主域的问题,可能还需要第一方和第三方 Cookie 共同使用才可以准确统计出 UV。
  总之 Cookie 是个大坑,如果可以的话我真不想再往里跳了,无状态的 REST API 才是我向往的。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^