session 跟cookie有是一对好基友。它们诞生与HTTP协议有一定的历史关系。
简单来说,session与cookie是为了满足HTTP协议1.1所不能满足需求,应运而生。但是这对好基友却不是协议层面的实事物,他们从本质上,是对HTTP协议的一种扩展
HTTP协议是无状态的,而session与cookie则是分别从服务器端与客户端去维护访问状态。
举个例子,今天你登录某网站,然后关了电脑,第二天开机,再次登录该网站,发现不需要再次输入用户名和密码。这是由于cookie在客户端保存了你的登陆信息或者说账户资料,并且该cookie对应于服务端拥有唯一标识的session,session保存了账户的访问状态,所以用户登陆后cookie会随着访问请求一起发送往服务端,服务端由此可以将用户当做已登陆来识别。而这个访问状态显然就是指数据(用户名或者密码之类的)。
cookie:
无论使用何种服务端技术,只要发送回的HTTP响应中包含如下形式的头,则视为服务器要求设置一个cookie:
Set-cookie:name=name;expires=date;path=path;domain=domain
支持cookie的浏览器都会对此作出反应,即创建cookie文件并保存(也可能是内存cookie),用户以后在每次发出请求时,浏览器都要判断当前所有的cookie中有没有没失效(根据expires属性判断)并且匹配了path属性的cookie信息,如果有的话,会以下面的形式加入到请求头中发回服务端:
Cookie: name="zj"; Path="/linkage"
服务端的动态脚本会对其进行分析,并做出相应的处理,当然也可以选择直接忽略。需要注意的是,出于安全性的考虑,cookie可以被浏览器禁用。
session:
它的基本原理是服务端为每一个session维护一份会话信息数据,而客户端和服务端依靠一个全局唯一的标识来访问会话信息数据。用户访问web应用时,服务端程序决定何时创建session,创建session可以概括为三个步骤:
1. 生成全局唯一标识符(sessionid)。
2. 开辟数据存储空间。一般会在内存中创建相应的数据结构。但是!这种情况下,系统一旦断电,所有的会话数据就会丢失,如果是电子商务网站,这种事故会造成严重的后果。不过也可以写到文件里甚至存储在数据库中,这样虽然会增加I/O开销,但session可以实现某种程度的持久化,而且更有利于session的共享。
3. 将sessionid发送给客户端。而发送sessionid又有两种方式:cookie和URL重写
cookie:服务端只要设置Set-cookie头就可以将session的标识符传送到客户端,而客户端此后的每一次请求都会带上这个标识符,由于cookie可以设置失效时间,所以一般包含session信息的cookie会设置失效时间为0,即浏览器进程有效时间。至于浏览器怎么处理这个0,每个浏览器都有自己的方案,但差别都不会太大(一般体现在新建浏览器窗口的时候)
URL重写:就如字面意思那样。在返回用户请求的页面之前,将页面内所有的URL后面全部以get参数的方式加上session标识符,这样用户在收到响应之后,无论点击哪个链接或提交表单,都会在再带上session的标识符,从而就实现了会话的保持。
如果客户端禁用了cookie的话,URL重写将会是首选。
那么这整个过程是怎样的呢?
当你访问某网址的时候,服务器返回的响应头里会有Set-cookie JSESSIONID="xx";Path="xx";name="xx";expires="xx";domain="xx";name="xx";
这个JSESSIONID里面的就是sessionid了,这就是服务器创建了seesion,记录了访问状态,并且告诉客户端浏览器以sessionid为唯一标示符,创建cookie。并且每次发出请求前都要去匹配所有cookie的Path属性,将相匹配的cookie以下面这种形式发送到服务端:
Cookie: JSESSIONID="xx";name="xx"; Path="xx";
服务端在识别cookie中的sessionid后会在服务端调用匹配的session对访问请求进行处理,再次返回的响应里就不会带有涉及session或者cookie的信息。
cookie和session都有可以设置有效期,一般来说session中默认有效期都是短时效的,例如Tomcat中Session的默认失效时间为30分钟,cookie的有效期。当然,也可以在有效期期间清除session或cookie,如手动清除cookie或session,关闭浏览器后引发session超时等。
有关session的手动销毁,这里有个小知识。当服务端销毁session后,客户端依旧发送cookie,这时服务端在找不到匹配的sessionid的情况下会重新创建新的session,并告知客户端更新sessionid开始保持新的会话。
我们再来看看session与cookie在其他方面的对比:
安全性
cookie将信息保存在客户端,如果不进行加密的话,安全性很差,即使加密也很容易就会被窃取。而session只会将信息存储在服务端,如果存储在文件或数据库中,也有被窃取的可能。session安全性方面比较突出的是存在会话劫持的问题,当sessionid被盗用,由于HTTP协议的无状态性,服务器无法得知session是否被劫持,但总的来讲安全性要高于cookie。
大小限制
Cookie的处理在开发中没有session方便。而且cookie在客户端是有数量和大小的限制的,而session的大小只以硬件为限制,能存储的数据大了很多。
网友评论