谈谈Session会话和Cookie

Session

Session在我们的网络应用中就是一种客户端与服务器端保持状态的解决方案

Session对象,就是客户端浏览器与服务器之间建立的互动信息状态。每一个不同的用户连接将得到不同的Session,也就是说Session与用户之间是一种一对一的关系

Session在用户进入网站时由服务器自动产生,并在用户正常离开站点时释放

Cookie

Cookie是WEB上最常用的跟踪用户会话方式,当  Cookie被禁止后,一般都用URL重写来跟踪会话。

Cookie是一种由服务器发送给客户的片段信息,存储在客户环境中,并在客户所有的对服务器的请求中都要发回它

cookies是一种WEB服务器通过浏览器在访问者的硬盘上存储信息的手段

Cookies给网站和用户带来的好处: 
  (1)、Cookie能使站点跟踪特定访问者的访问次数、最后访问时间和访问者进入站点的路径 
  (2)、Cookie能告诉在线广告商广告被点击的次数,从而可以更精确的投放广告 
  (3)、Cookie有效期限未到时,Cookie能使用户在不键入密码和用户名的情况下进入曾经浏览过的一些站点 
     (4)、Cookie能帮助站点统计用户个人资料以实现各种各样的个性化服务,其实,cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力.

四、Session机制 
Session机制采用的是在服务器端保持状态的方案。 
当用户访问到一个服务器,服务器就要为该用户创建一个SESSION,在创建这个SESSION的时候,服务器首先检查这个用户发来的请求里是否包含了一个SESSIONID,如果包含了一个SESSIONID则说明之前该用户已经登陆过并为此用户创建过SESSION,那服务器就按照这个SESSIONID把这个SESSION在服务器的内存中查找出来(如果查找不到,就有可能为他新创建一个),如果客户端请求里不包含有SESSIONID,则为该客户端创建一个SESSION并生成一个与此SESSION相关的SESSIONID。这个SESSIONID是唯一的、不重复的、不容易找到规律的字符串,这个SESSIONID将被在本次响应中返回到客户端保存,而保存这个SESSIONID的正是COOKIE,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。

我们知道在IE中,我们可以在工具的internet选项中把COOKIE禁止,那么会不会出现把客户端的COOKIE禁止了,SESSIONID就无法再用了呢?

可以有其他机制在COOKIE被禁止时仍然能够把Session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把Session id直接附加在URL路径的后面一种是作为URL路径的附加信息,表现形式为: http://…./xxx;jSession=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764;

另一种是作为查询字符串附加在URL后面,表现形式为: http://…../xxx?jSession=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 

还有一种就是表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把Session id传递回服务器。
我们常说的在一个IE被打开是创建一个Session,当关闭IE时Session也就被删除,事实上,除非程序通知服务器删除Session,否则Session会被服务器一直保留,直到Session的失效时间到了自动删除。服务器不知道IE被关闭,IE不会主动在其关闭之前通知服务器它将要关闭。程序一般都是在用户做注销时删除Session。我们产生这种错觉的原因是:一般Session机制都使用cookie来保存Session id,而一旦关闭IE浏览器,Session id就不存在了,再连接服务器时找不到原来的Session了.如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的 HTTP请求头,把原来的Session id发送给服务器,则再次打开浏览器仍然能够找到原来的Session。恰恰是由于关闭浏览器不会导致Session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用Session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把Session删除以节省存储空间。 
一般情况下,Session都是存储在内存里,当服务器进程被停止或者重启的时候,内存里的Session也会被清空,如果设置了Session的持久化特性,服务器就会把Session保存到硬盘上,当服务器进程重新启动或这些信息将能够被再次使用。

三、Cookie机制 
Cookie机制采用的是在客户端保持状态的方案。 
Cookie机制,就是当服务器对访问它的用户生成了一个Session的同时服务器通过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie,保存在客户端,里面记录着用户当前的信息,当用户再次访问服务器时,浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置也就是对应的Cookie文件。 若存在,则把该cookie附在请求资源的HTTP请求头上发送给服务器,例如:当我们登陆了一个网站,并且填写了有关资料,以本站会员的名义登陆上了有关网页,这时你把浏览器关闭,再重启进入该网站的某一个页面时是以你登陆过的会员进去的,当然,不是所有网站都是这样,我们知道,cookie的保存有临时性的和持久性的,大多都是临时性的,也就是cookie只保存在客户端的内存中,而没有保存在硬盘上,当关闭浏览器,cookie也就销毁。以下是有关cookie机制的一些具体说明: 
cookie的内容主要包括:名字,值,过期时间,路径和域。 
其中域可以指定某一个域比如.google.com,相当于总店招牌,比如宝洁公司,也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.com,可以用飘柔来做比。 
路径就是跟在域名后面的URL路径,比如/或者/foo等等,可以用某飘柔专柜做比。路径与域合在一起就构成了cookie的作用范围。 
如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的 cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。 
存储在硬盘上的cookie可以在不同的浏览器进程间共享

比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。

对于微软的IE浏览器,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;

对于火狐狸firefox浏览器,所有的进程和标签页都可以共享同样的cookie。

一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。

浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用Session机制的web应用程序开发者造成很大的困扰。

五、常见问题 
1、Session在何时被创建 
Session在有客户端访问时就被创建,

然而事实是直到某server端程序调用HttpServletRequest.getSession(true)这样的语句时才被创建,

注意如果JSP没有显示的使用 <%@page Session=”false”%> 关闭Session,则JSP文件在编译成Servlet时将会自动加上这样一条语句HttpSession Session =

HttpServletRequest.getSession(true);这也是JSP中隐含的Session对象的来历。由于Session会消耗内存资源,因此,如果不打算使用Session,应该在所有的JSP中关闭它。 
2、Session何时被删除

综合前面的讨论,Session在下列情况下被删除: 
a.程序调用HttpSession.invalidate(); 
b.距离上一次收到客户端发送的Session id时间间隔超过了Session的超时设置; 
c.服务器进程被停止(非持久Session)。 
3、如何做到在浏览器关闭时删除Session ?
严格的讲,做不到这一点。可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除Session。但是

对于浏览器崩溃或者强行杀死进程这些非常规手段仍然无能为力。

4、有个HttpSessionListener是怎么回事

你可以创建这样的listener去监控Session的创建和销毁事件,使得在发生这样的事件时你可以做一些相应的工作。

注意是Session的创建和销毁动作触发listener,而不是相反。类似的与HttpSession有关的listener还有HttpSessionBindingListener,HttpSessionActivationListener和 HttpSessionAttributeListener。

5、存放在Session中的对象必须是可序列化的吗 ?

不是必需的。要求对象可序列化只是为了Session能够在集群中被复制或者能够持久保存或者在必要时server能够暂时把Session交换出内存。在Weblogic Server的Session中放置一个不可

序列化的对象在控制台上会收到一个警告。

6、开两个浏览器窗口访问应用程序会使用同一个Session还是不同的Session 
对Session来说是只认id不认人,因此不同的浏览器,不同的窗口打开方式以及不同的cookie存储方式都会对这个问题的答案有影响。 
7、如何防止用户打开两个浏览器窗口操作导致的Session混乱 
这个问题与防止表单多次提交是类似的,可以通过设置客户端的令牌来解决。就是在服务器每次生成一个不同的id返回给客户端,同时保存在Session里,客户端提交表单时必须把这个id也返回服务器,程序首先比较返回的id与保存在Session里的值是否一致,如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表示层模式的部分。需要注意的是对于使用javascript window.open打开的窗口,一般不设置这个id,或者使用单独的id,以防主窗口无法操作,建议不要再window.open打开的窗口里做修改操作,这样就可以不用设置。 
8、为什么Session不见了 
排除Session正常失效的因素之外,服务器本身的可能性应该是微乎其微的;理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题。出现这一问题的大部分原因都是程序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。

9、服务器关掉后,当前Session会丢掉吗?

这个取决于你使用什么样的web服务器以及web服务器是如何配置的。

tomcat在shutdown前默认会自动将Session保存到指定的目录中,重新启动是重新加载,因此tomcat重新启动后,Session是可以继续使用的。

此外,你还何以将Session保存到数据库中,这个要在server.xml中配置。

10、Cookie的过期和Session的超时有什么区别?

Session的超时由服务器来维护,它不同于Cookie的失效日期。

首先,会话一般基于驻留内存的cookie不是持续性的cookie,因而也就没有截至日期。即使截取到JSESSION cookie,并为它设定一个失效日期发送出去。

浏览器会话和服务器会话也会截然不同。

上一篇:关于jQuery的cookies插件2.2.0版设置过期时间的说明


下一篇:即使我的活动在android 2.3.1中处于纵向模式,如何将framelayout设置为横向