今天對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">。