今天对cookie进行了一番学习,通过一些测试程序,对cookie的工作方式有了一个大概的了解。
在bs的架构中,浏览器作为客户端,与服务器之间通过session保持连接状态。以前面试的时候,经常被问及一个问题:浏览器禁止cookie时,服务器与客户端浏览器能否保持session连接?
其实要完全回答正确这个问题,需要对cookie的作用有全面的了解。具体cookie的解释大家可以google一下。我以前一直有一个误解(估计很多人都有),以为cookie就是一个文件,用来保存用户信息或者其他信息。如果这么认为的话,那么浏览器禁用cookie也就是不保存成文件而已,并不影响浏览器与服务器交互。其实如果我们看看浏览器发出的http请求消息和服务器的http响应消息就一目了然了。
Http request:
GET /cluster/index.jsp HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive
Http response:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=4918D6ED22B81B587E7AF7517CE24E25.server1; Path=/cluster
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 377
Date: Tue, 02 Mar 2010 02:58:32 GMT
这是我们打开浏览器后,第一次请求一个网址时的请求和响应消息(如果客户本地没有该网址的cookie)。首先看response消息,可以看到一行醒目的字符串Set-Cookie: JSESSIONID=1363B650B295DE9494A33805F62BC5ED.server1; Path=/cluster。其实这行是在告诉客户端浏览器,把这段cookie保存下来,根据cookie的存活时间,这段cookie信息有可能只存在在内存中,也可能保存到文件中。下面不关闭浏览器,再次请求同样的url,观察第二次的请求和响应消息:
Http request:
GET /cluster/user_details.jsp HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Accept-Language: zh-cn
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; InfoPath.2; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Accept-Encoding: gzip, deflate
Host: localhost:8080
Connection: Keep-Alive
Cookie: JSESSIONID=4918D6ED22B81B587E7AF7517CE24E25.server1
Http response
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=4918D6ED22B81B587E7AF7517CE24E25.server1; Expires=Tue, 02-Mar-2010 22:15:38 GMT
Content-Type: text/html
Content-Length: 252
Date: Tue, 02 Mar 2010 05:35:38 GMT
这个时候注意看请求信息中多了一行Cookie,浏览器将这个Cookie信息传递给服务器,这次服务器返回的Set-Cookie中的JSESSIONID就和请求的JSESSIONID一致了。
通过这两次实验,总结出以下几点:
1.session是什么?session其实是在无状态会话的http协议下,为了实现有状态会话而设计的一种实现方法。
2.如何实现session会话?简单的说,就是在服务器端创建session对象,记录会话信息,同时在客户端与服务器的交互过程中,通过JSESSIONID字符串唯一标识session对象(客户端只需要保存JSESSIONID这个字符串,服务器端只需要保存JSESSIONID和真实的session对象之间的关联关系),而这个JSESSIONID字符串就是通过http协议的cookie功能实现的。
3.浏览器禁用cookie时会发生什么?浏览器禁止了Cookie,那么第二次请求中将不包含有Cookie信息(当然更不存在JSESSIONID信息),服务器也就不会收到JSESSIONID的值,于是服务器认为是新请求,又创建一个服务器session,同时将本次生成的JSESSIONID再次通过响应信息中的Set-Cookie返回给客户端。如此循环交互,服务器将永远认为该客户浏览器的请求是新请求,因此无法实现session功能。
最后回到最初的那个面试问题:浏览器禁止cookie时,服务器与客户端浏览器能否保持session连接?当然可以,但是现在不能依靠浏览器自动完成这个功能,而是需要服务器端通过重写URL的方法来实现,就是在返回的页面中,在URL里将JSESSIONID的值作为请求参数传递给服务器端,例如<a href="http://www.java.com;JSESSIONID=4918D6ED22B81B587E7AF7517CE24E25">。