<a href="http://wenku.baidu.com/link?url=LHGfGGijeHw2LDSfcnbHixX2vJj5nqvq2ei5axd74tbu7XHGeSNeojRVTnTCmwftSxFrZF4Ojq41ySgZjlwfPEYsMPfWxeVcTnH3tH1LSIO" target="_blank">http://wenku.baidu.com/link?url=LHGfGGijeHw2LDSfcnbHixX2vJj5nqvq2ei5axd74tbu7XHGeSNeojRVTnTCmwftSxFrZF4Ojq41ySgZjlwfPEYsMPfWxeVcTnH3tH1LSIO</a>
具體來說cookie機制采用的是在用戶端保持狀态的方案,而session機制采用的是在伺服器端保持狀态的方案。
而到了web伺服器蓬勃發展的時代,session在web開發語境下的語義又有了新的擴充,它的含義是指一類用來在用戶端與伺服器之間保持狀态的解決方案 ④。有時候session也用來指這種解決方案的存儲結構,如“把xxx儲存在session裡”⑤。由于各種用于web開發的語言在一定程度上都提供了對這種解決方案的支援,是以在某種特定語言的語境下,session也被用來指代該語言的解決方案,比如經常把Java裡提供的javax.servlet.http.HttpSession簡稱為session⑥
正統的cookie分發是通過擴充HTTP協定來實作的,伺服器通過在HTTP的響應頭中加上一行特殊的訓示以提示浏覽器按照訓示生成相應的cookie。然而純粹的用戶端腳本如JavaScript或者VBScript也可以生成cookie。
cookie的内容主要包括:名字,值,過期時間,路徑和域。
其中域可以指定某一個域比如.google.com,相當于總店招牌,比如寶潔公司,也可以指定一個域下的具體某台機器比如www.google.com或者froogle.google.com,可以用飄柔來做比。
路徑就是跟在域名後面的URL路徑,比如/或者/foo等等,可以用某飄柔專櫃做比。
路徑與域合在一起就構成了cookie的作用範圍。
如果不設定過期時間,則表示這個cookie的生命期為浏覽器會話期間,隻要關閉浏覽器視窗,cookie就消失了。這種生命期為浏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬碟上而是儲存在記憶體裡,當然這種行為并不是規範規定的。如果設定了過期時間,浏覽器就會把cookie儲存到硬碟上,關閉後再次打開浏覽器,這些cookie仍然有效直到超過設定的過期時間。
session機制是一種伺服器端的機制,伺服器使用一種類似于散清單的結構(也可能就是使用散清單)來儲存資訊。
當程式需要為某個用戶端的請求建立一個session的時候,伺服器首先檢查這個用戶端的請求裡是否已包含了一個session辨別- 稱為session id,如果已包含一個session id則說明以前已經為此用戶端建立過session,伺服器就按照session id把這個session檢索出來使用(如果檢索不到,可能會建立一個),如果用戶端請求不包含session id,則為此用戶端建立一個session并且生成一個與此session相關聯的session id,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字元串,這個session id将被在本次響應中傳回給用戶端儲存。 儲存這個session id的方式可以采用cookie,這樣在互動過程中浏覽器可以自動的按照規則把這個辨別發揮給伺服器。一般這個cookie的名字都是類似于SEEESIONID,而。比如weblogic對于web應用程式生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。
由于cookie可以被人為的禁止,必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回伺服器。經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面,附加方式也有兩種,一種是作為URL路徑的附加資訊,表現形式為http://...../xxx;jsessionid=ByOK ... 99zWpBng!-145788764
另一種是作為查詢字元串附加在URL後面,表現形式為http://...../xxx?jsessionid=ByOK ... 99zWpBng!-145788764
在談論session機制的時候,常常聽到這樣一種誤解“隻要關閉浏覽器,session就消失了”。其實可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易删除顧客的資料。對session來說也是一樣的,除非程式通知伺服器删除一個session,否則伺服器會一直保留,程式一般都是在使用者做log off的時候發個指令去删除session。然而浏覽器從來不會主動在關閉之前通知伺服器它将要關閉,是以伺服器根本不會有機會知道浏覽器已經關閉,之是以會有這種錯覺,是大部分session機制都使用會話cookie來儲存session id,而關閉浏覽器後這個session id就消失了,再次連接配接伺服器時也就無法找到原來的session。如果伺服器設定的cookie被儲存到硬碟上,或者使用某種手段改寫浏覽器發出的HTTP請求頭,把原來的session id發送給伺服器,則再次打開浏覽器仍然能夠找到原來的session。
恰恰是由于關閉浏覽器不會導緻session被删除,迫使伺服器為seesion設定了一個失效時間,當距離用戶端上一次使用session的時間超過這個失效時間時,伺服器就可以認為用戶端已經停止了活動,才會把session删除以節省存儲空間。
HttpSession是Java平台對session機制的實作規範,因為它僅僅是個接口,具體到每個web應用伺服器的提供商,除了對規範支援之外,仍然會有一些規範裡沒有規定的細微差異。
1、session在何時被建立
一個常見的誤解是以為session在有用戶端通路時就被建立,然而事實是直到某server端程式調用HttpServletRequest.getSession(true)這樣的語句時才被建立,注意如果JSP沒有顯示的使用 關閉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。但是對于浏覽器崩潰或者強行殺死程序這些非正常手段仍然無能為力。
七:跨應用程式的session共享
想使用session來實作SSO(single sign on),在session中儲存login的使用者資訊,最自然的要求是應用程式間能夠通路彼此的session。
然而按照Servlet規範,session的作用範圍應該僅僅限于目前應用程式下,不同的應用程式之間是不能夠互相通路對方的session的。各個應用伺服器從實際效果上都遵守了這一規範,但是實作的細節卻可能各有不同,是以解決跨應用程式session共享的方法也各不相同。
首先來看一下Tomcat是如何實作web應用程式之間session的隔離的,從Tomcat設定的cookie路徑來看,它對不同的應用程式設定的cookie路徑是不同的,這樣不同的應用程式所用的session id是不同的,是以即使在同一個浏覽器視窗裡通路不同的應用程式,發送給伺服器的session id也可以是不同的。
session機制本身并不複雜,然而其實作和配置上的靈活性卻使得具體情況複雜多變。這也要求我們不能把僅僅某一次的經驗或者某一個浏覽器,伺服器的經驗當作普遍适用的經驗,而是始終需要具體情況具體分析。
session與cookie差別
Session是由應用伺服器維持的一個伺服器端的存儲空間,使用者在連接配接伺服器時,會由伺服器生成一個唯一的SessionID,用該SessionID為辨別符來存取伺服器端的Session存儲空間。而SessionID這一資料則是儲存到用戶端,用Cookie儲存的,使用者送出頁面時,會将這一SessionID送出到伺服器端,來存取Session資料。這一過程,是不用開發人員幹預的。是以一旦用戶端禁用Cookie,那麼Session也會失效。
伺服器也可以通過URL重寫的方式來傳遞SessionID的值,是以不是完全依賴Cookie。如果用戶端Cookie禁用,則伺服器可以自動通過重寫URL的方式來儲存Session的值,并且這個過程對程式員透明。
可以試一下,即使不寫Cookie,在使用request.getCookies();取出的Cookie數組的長度也是1,而這個Cookie的名字就是JSESSIONID,還有一個很長的二進制的字元串,是SessionID的值。
Cookie是用戶端的存儲空間,由浏覽器來維持。
本文轉自韓立偉 51CTO部落格,原文連結:http://blog.51cto.com/hanchaohan/1532414,如需轉載請自行聯系原作者