1.1 Cookie概念与技术
What Cookie
根据维基百科的定义:HTTP Cookie,也称为web cookie、互联网cookie、浏览器cookie,是指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。
即cookie本质是一段标识用户身份的数据。它用于记录浏览网站时的状态信息(如电商网站购物车中的商品)与动作信息(如登陆、点击特定按钮、访问网特定网页等)。
Why Cookie
众所周知,HTTP协议是无状态的,这才使得有必要创造一个叫做cookie的机制,来给HTTP打上补丁。正如RFC6265文档所说:cookie 『leting the servers maintain a stateful session over the mostly stateless HTTP protocol』。
那么问题来了,为什么当初HTTP协议设计没有保持状态的机制?换句话说,为什么HTTP协议在制定的时候没有将存储状态信息纳入,作为协议的一部分?概括起来,大致有两点:
- 节省计算资源: 为了提高web服务器对并发访问的处理能力(因为考虑到面对大量客户端浏览器的并发请求时,尽量少的计算情形可以减少服务器计算资源)。
- 节省存储资源:早期的存储价格十分昂贵...
所以从计算与存储两方面考虑,在设计HTTP协议时规定:web服务器发送HTTP响应时,不会保存发出请求的浏览器的任何状态信息。这样一来,可大大节省服务器资源。
然而,当客户端与服务器进行动态交互的web应用程序出现之后,HTTP这种无状态的特性则严重阻碍了这些应用的实现,因为交互是需要承前启后的。如用户从一个页面跳转至另一个页面将被认为是一个全新的用户(之前的信息一概不知),典型的场景便是电商网站的购物车,由于HTTP协议的无状态性,网站无法知道用户之前选择了那些商品。这时cookie技术便出现了。
总而言之:Cookies是作为HTTP的一个扩展诞生的,主要用途是弥补HTTP的无状态特性。
注:协议的『状态性』是指:下一次传输可以记住本次传输信息的能力。
由于 HTTP协议无状态,若想提高客户端请求服务器的效率,则需要一种状态管理机制,用户保存客户端请求服务器的状态,即保存请求服务器的客户端信息,即识别客户端,使得数据可以跨页面交换(相对,session则是统一管理所有用户状态的机制 - 每个客户端设置一个唯一标识:sessionID),这时cookie就犹如这些页面之间的快速数据通道一般,不管用户去了网站的哪里、干了什么,皆可追踪。
cookie作为HTTP协议的补充(或补丁),它独立于语言存在,由浏览器实现和管理(即不同的浏览器可能有不同的cookie实现与管理机制,即无法跨浏览器共享cookie)。其中关于cookie的RFC文档主要有:RFC6265、RFC2109。
关于服务端设置cookie
cookie主要是参考RFC2109标准由客户端实现其生成、使用等整个管理过程。而服务器端则只需参照此标准,实现与客户端之间的交互指令。 如使用php设置cookie命令,实际上PHP并没有真正设置过cookie,甚至可以说:php根本没有这个能力设置cookie(不符合标准),它只是发出命令让浏览器来做这件事情而已。
cookie实现原理
cookie主要由服务器主动发起设置命令,而由客户服负责配合具体执行。
- 客户端 --request-->服务器 —response(设置cookie的命令)—>客户端:如果服务器需要记录该用户,则使用response,向客户端浏览器'颁发'一个cookie。
- 客户端 --request(cookie)-->服务器-->检查cookie,识别用户:浏览器则会把cookie保存起来。当浏览器再此请求该网站服务器时,浏览器会把请求的网址连同该cookie一个提交给服务器。服务器检查该cookie,以此来辨识用户。
注:由于cookie是存储于浏览器中(保存在文件(如IE是每个域名下一个文本文件;Firefox保存在sqlite数据库中 - 以cookie.sqlite文件形式)或内存中),则每个浏览器客户端(可细分指每个域名下)有自己的cookie。 关闭浏览器时,Cookie并不会随之消失,除非设置该cookie的expire为空。因为没有设置过期时间,浏览器默认将该cookie保存在内存中。 此外,还有一个cookie,由FLASH创建,称为:Flash Shard Object,又称:Flash Cookie,即使清空浏览器所有隐私数据,这类cookie还是会存在硬盘上,因为它们不受浏览器管理,而是由Flash管理。
关于cookie的数量
每个域名下允许的cookie数据是有限制的,由浏览器决定。例如:
- IE8规定一个域名可以存放50个cookie。
- Firefox规定一个域名可以存150个cookie。
cookie,可以提升用户体验与便捷操作,但是cookie的数量过多的话,会增加带宽(因为这些cookie是会在request时随其他参数一起传递给服务器)。
注:一般cookie被设置在某个域下,则请求该域名下的一个资源,浏览器和服务器之间都可能存在cookie的上行与下行流量。看似一个很小cookie,在一个页面请求就可能产生十几KB流量,故不可滥用cookie - 可通过使用Fiddler进行抓包验证此结论。
cookie的缺陷:
- 增加了带宽:cookie会被附加在每个HTTP请求中,这无形中增加了流量。
- 不安全:由于在HTTP请求中,cookie是明文传递的,所以存在安全问题 - 除非用HTTPS。
- 大小有限:cookie的大小限制在4k左右,这对于复杂的存储需求来说是不够用的。
References
1、https://en.wikipedia.org/wiki/HTTP_cookie
2、https://zh.wikipedia.org/wiki/Cookie
3、https://tools.ietf.org/html/rfc6265
4、https://tools.ietf.org/html/rfc2109