【HTTP】三、HTTP状态保持机制(Cookie和Session)
前面我们提到HTTP协议的特点:无连接、无状态。无连接带来的时间开销随着HTTP/1.1引入了持久连接的机制得到了解决。现在来关注其“无状态”的特点。
所谓的无状态,就是指服务器不记录用户的信息,对于事务处理没有记忆能力,无法根据之前的状态进行本次的请求处理。这样做虽然简化了服务器的设计,但是实际工作中,一些万维网网点却很希望可以识别用户,记录用户的一些行为,比如购物网站,用户在选号一件物品后,还要继续选购其他物品,此时服务器希望记住用户的身份。再比如对于一个用户登录的页面,无状态意味着每次跳转新页面不是要再次登录, 就是要在每次请求报文中附加参数来管理登录状态,因此势必会带来一些问题。
Cookie和Session就是在客户端和服务器之间保持状态的解决方案,它弥补了HTTP无状态的缺陷。
为了理解Cookie和Session,先来举一个例子(来源于网络,特此说明):
一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
- 该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
- 发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
- 发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
这个例子可以说是非常形象了,几乎可以瞬间理解Cookie和Session的区别,首先,HTTP协议为了简单灵活,本身就是无状态的,因此并不想将其设置为有状态,否定了方法一。因此,要想维护状态就只有方法二和方法三,也就是说:客户端保持状态和在服务器端保持状态两种,这正好对应了Cookie和Session这两种解决方案。同时,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上并不是只有这一种方式。
1、Cookie机制
首先,Cookie是在客户端保持状态的方法。当某个客户端首次请求服务端时,服务端会生成一些状态信息,然后再给客户端的响应报文中添加一个首部字段:“Set-cookie”,名字是“Set-cookie”,值为Cookie的内容,因此这些状态信息就随着响应报文回到客户端,当客户端收到这样的响应时,就在它管理的Cookie文件中添加一行,将这一个Cookie值记录下来。随后,当这个客户端下一次浏览这个网站时,每发送一个HTTP请求报文,就在Cookie文件中取出对应的那一行内容,放到首部行中,一起发送给服务端,进而服务端就知道了该客户端之前的一些状态信息。
具体的,cookie的内容主要包括:名字,值,过期时间,路径和域。 路径与域一起构成了cookie的范围。如果未设置到期时间,则表示此cookie的生命周期是在浏览器会话期间,浏览器窗口关闭,并且cookie消失。生命周期为浏览器会话的cookie称为会话cookie。会话cookie通常不存储在硬盘上,而是存储在内存中。存储在硬盘上的Cookie可以在不同的浏览器进程之间共享。
当然,这个Cookie实际上是记录了用户在万维网上的一些行为,这属于个人隐私,为了让用户有拒绝接受Cookie的自由,在浏览器中可以进行相应的设置来关闭Cookie。
2、Session机制
对于Session会话机制,其实有了前面的例子也不难理解了,它是一种服务器端维护状态的机制,使用类似哈希表这样的结构来保存信息。
当程序需要为客户端的请求创建会话时,服务器首先检查客户端的请求是否包含会话标识符(称为会话ID)。如果包含它,它先前已为此客户端创建了一个会话。服务器根据会话ID检索会话(无法检索,将创建新会话),如果客户端请求不包含会话ID,则为客户端创建会话并生成与会话关联的会话ID。 session id应该是一个既不重复也不容易被复制的字符串。会话ID将返回给客户端以保存此响应。
那么这个Session Id如何返回到客户端呢,这可以使用cookie的方式,将其放到首部行中返回给客户端进行保存,如果禁用了Cookie,可以适应URL重写的方法,将ID附加到URL中返回去。
3、Cookie和Session的对比
那么总结起来,我们看看Cookie和Session的区别究竟在哪里。
- 不同的存储位置。Cookie将状态信息保持在客户端,Session保存在服务端,这是最大的区别。
- 不同的数据类型。只有ASCII字符串可以存储在cookie中,而Session采用哈希表的方式,可以保存任意类型的数据。
- 不同的隐私政策和安全性。Cookie存储在客户端阅读器中,对客户端可见,因此可能会产生伪装等安全问题,所以尽量不要用Cookie来保存敏感信息,或者采取加密的方法,而Session会话存储在服务器上,对客户端是透明的。不存在敏感信息泄露的风险。
- 有效期的差异。将Cookie的过期时间设为一个很大的值就可以实现永久记录信息,而Session Id可能会依赖Cookie,如果到时时间太短,Session会很快失效,而过期时间太长,会使得服务器端累积大量的Session,导致内存溢出。
- 不同的服务器压力。Session保留在服务器端,每个用户都将生成一个会话。如果有很多并发用户,它会产生大量的Session并消耗大量内存。因此,具有高并发流量的站点不太可能使用Session来跟踪客户会话。而Cookie保留在客户端上,不消耗服务器资源。如果有很多用户同时阅读,那么cookie是一个不错的选择,比如Google、Baidu、Sina,cookies可能是唯一的选择。
- 单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的cookie不能超过3K。
参考链接:
https://www.cnblogs.com/lonelydreamer/p/6169469.html
https://baijiahao.baidu.com/s?id=1612804856429135825&wfr=spider&for=pc