前言
为什么说HTTP是无状态,有会话的?
HTTP是无状态的:在同一个连接中,两个执行成功的请求之间是没有关系的。这就带来了一个问题,用户没有办法在同一个网站中进行连续的交互,比如在一个电商网站里,用户把某个商品加入到购物车,切换一个页面后再次添加了商品,这两次添加商品的请求之间没有关联,浏览器无法知道用户最终选择了哪些商品。而使用HTTP的头部扩展,HTTP Cookies就可以解决这个问题。把Cookies添加到头部中,创建一个会话让每次请求都能共享相同的上下文信息,达成相同的状态。
注意,HTTP本质是无状态的,使用Cookies可以创建有状态的会话。
上述是官方文档中的描述,而将上述文档通俗来讲就是说:
每个请求之间都是毫无关联的,互相都影响不了对方,也无法了解对方的内部细节,更无从谈起相互协作。
下面博主以一个简单的对话向大家简单解释一下其效果:
可以发现,在GreatBiscuit进行第二次“请求”时,猪小馨根本就没将其与第一次请求相结合起来,进而导致了这段对话。
但在平时的生活中,很多请求间都应该是要互相之间有关联的,譬如官方文档中所举的例子:在淘宝中购物,购物车中的商品应该是每次加入购物车就增加一个;而不是每次在新商品加入购物车时,旧商品就消失不见了。
而应该如何解决这一问题呢?
我们可以采用Session进行会话管理。
一、浏览器的Cookie机制
官方文档对Cookie的解释是:
HTTP Cookie(也叫 Web Cookie 或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的HTTP协议记录稳定的状态信息成为了可能。
对于官方文档,博主绘制了如下所示的图片来帮助大家理解:
- 在 1 中,浏览器向服务器发出请求,但此时的Cookie是没有作用的,因为里面没有任何有价值的信息。
- 在 2 中,服务器返回给浏览器的set cookie其实就是服务器给浏览器颁发的一张身份证。浏览器会把它存储在本地。以后浏览器再发来请求就会携带上这个Cookie,使服务器能够判别出它。
- 在 3 中,浏览器的今后的请求都会带上服务器所给的Cookie。
- 在 4 中,服务器通过浏览器带来的Cookie识别出浏览器,并给其提供“连续”的服务。
二、Session
仅仅依靠Cookie就够了吗?
实际上,如果愿意的话,仅仅使用Cookie是可以达到目标的。但是,需要将每次的状态(可以理解为操作系统中的中断现场)都放在Cookie里传回浏览器,并在下次请求时送往服务器以进行“连续”服务。
但是,这样会出现一系列问题:
- 首先,状态信息过大,耗费资源。
- 其次,将状态信息置于客户端很不安全。
- 不再赘述
所以,仅仅使用Cookie是不适合的。于是,我们可以在浏览器中存储下状态信息,即被称为Session。
如下所示的图画就是在上图上进行改造,增加Session的效果:
浏览器在进行请求后,浏览器产生状态信息(Session),并将其保存下来。而将Session的唯一标识SessionID置于Cookie中返回给浏览器保存起来。以此解决会话管理问题。
三、总结
对于该过程进行总结如下:
- 浏览器第一次发送请求
- 服务器生成Session(状态信息)保存于本地,并将SessionID放在Cookie中响应给浏览器
- 浏览器后续的请求都会携带这一Cookie
- 服务器通过浏览器中携带的Cookie识别出浏览器,并为其提供“连续”的服务。
至此,开头对话中的问题就可以解决了。