问题来源
昨晚需求上线之后测试报告了一个问题(什么问题这里暂且不关注),经过大佬们的讨论之后得出一个结论:根域下的cookie满了,把登陆态挤掉了。
作为一名菜鸡,不太能理解这个说法,但查询了一些资料之后,理解了大概的意思,这里做一个记录,同时也给大家分享下。
域名以及域名之间的关系
首先介绍一下域名系统(DNS)。域名分为根域、顶级域、二级域以及子域。
1. 根域
根域是 0 级域,以隐含的空标签(.)表示,但是通常不显示,例如 .com 、 .cn 后面都隐藏了一个根域点,实际对应的是 .com. 、 .cn.(PS:可以了解一下完全合格域名(FQDN)),在使用 dig 进行 DNS 解析的时候,可以看到根域名会出现在结果中:
dig +trace baidu.com
根域是域名系统的最顶层,所有的顶级域都隶属于根域。
2. 顶级域(TLD)
顶级域也被称为一级域,是显式可见的第一级域名,像之前提到的 .com 、 .cn 都是顶级域名,是域名的最高层级分类。
一般来说,顶级域主要有三大分类,通用顶级域(gTLD)、国家代码顶级域(ccTLD)、赞助顶级域(sTLD)。
通用顶级域典型代表就是 .com、.net、.org,这类是非地理特定的,适用于广泛用途。
国家代码顶级域基于国家/地区代码而定的,例如 .cn 是中国国家顶级域名、.us 是美国顶级域名、.jp 是日本顶级域名,通常用于本地化域名。
赞助顶级域名是有特定的机构或社群管理的,用于特定用途或成员的一类域名,例如 .edu、.gov、.aero。
除了这些分类之外,还有一些比较特殊的域名,比如 .localhost,这里不做介绍,感兴趣的可以去了解一下。
3. 二级域
二级域直接隶属于顶级域,是用户通常注册的域名部分,唯一标识组织或者个人在特定顶级域下的身份,例如 baidu.com 就标识在 .com 顶级域下的名叫 baidu 的二级域。
4.子域
子域是一个比较广泛的概念,是指三级及三级以下域的统称,是二级域的使用者根据需要自行划分,用于细分各个资源和服务,例如 yiyan.baidu.com 、www.baidu.com 、map.baidu.com,这些都是百度基于自身提供的一些服务具体划分的子域。
PS:域名系统大致就是这样划分的,当然,在日常的使用中,我们提到的根域可能代表的并不是域名划分中的根域,而是公司或者个人注册的二级域名,文章开头提到的根域就是指的公司注册的二级域名。
Cookie的共享机制
关于 cookie 的相关介绍可以参考阿里云的这篇文章 浏览器Cookie详解,这里就不再赘述,我们主要了解下 Cookie 的共享机制。
Cookie 的共享机制是基于域名系统的,通过设置 domain 属性来实现在同一个父域下不同的子级域实现共享,如果不设置 domian 属性则会默认仅在当前域名下使用。
这里以百度的 cookie 为例:

可以看到图中 Dimain 有好几个不同的值:.baidu.com 、 www.baidu.com 、 .passport.baidu.com、passport.baidu.com,这四个值分别代表 cookie 不同的作用域,首先 .baidu.com 表示的是在 baidu.com 这个二级域名下的所有子域进行共享 cookie,二级域名前面的点可以理解成通配符。
打开百度地图web端可以看到,Domain 属性为 .baidu.com 的cookie在这里同样可以找到,并且值是一样的,删除某个共享 cookie 之后,回到百度之后可以看到同样也被删除了。
其次是 www.baidu.com ,这个值表示的是当前 cookie 只在 www.baidu.com 这个域可用,在百度地图的 cookie 中是找不到这个 key 的。第三个和第四个也是同样的道理, .passport.baidu.com 代表在所有的 *.passport.baidu.com 中进行共享,而 passport.baidu.com 表示仅在 passport.baidu.com 域名下使用。
Cookie的数量限制
浏览器会限制每个域下能够添加的 cookie 数量,根据浏览器不同,限制也不相同,但最多不会超过 60 个。当前域下的 cookie 数量达到上限之后,浏览器会把旧的 cookie 删除或者拒接新增 cookie。
值得注意的是,通过父域向子域共享的 cookie 数量是不计入子域的 cookie 数量的,也就是说,假如父域向子域共享了 20 个 cookie,这 20 个 cookie 并不会受浏览器的数量限制,子域设置的 cokie 数量依旧是从 0 开始计算的。
结论
回到最初的那个问题,大佬所说的根域下的cookie满了,把登陆态挤掉了 ,其实是指公司的二级域下的 cookie 数量达到上限了,在某个子域中设置公司二级域下的 cookie 的时候浏览器把单点登录时设置的代表登录状态的 cookie 给删除了,所以才导致了这个问题。
OK,菜鸡又学到一个新知识点!