作為一名WEB開發程序員,對session的理解是最基礎的,但是現狀是WEB程序員遍地都是,隨便一划拉一大把,不過估計能把session能透徹理解的人應該不是很多,起碼我之前對此是知之甚少,偶然看到的一個關於session的文章,經過適當整理,特拿來與大家分享,因為時間太久,文章出處已然記不清楚,無法附上,請原作理解,若有必要我會刪除,謝謝!
目 錄
一、Session
二、Cookies
三、Cookies機制
四、Session機制
五、Cookies機制與Session機制的區別和聯系
六、常見問題
七、Session的用法
Session是WEB上有效的信息交互手段,因其使用方便、穩定、安全、可靠而被眾多WEB開發者所認知。尤其在互聯網身份驗證、網上電子購物等方面的應用更為廣泛。下面就着重來介紹下Session。
一、Session
Session,在漢語中表示通話、會話、對話(期)、話路[對談時間]的意思,其本來的含義一個終端用戶與交互系統進行通信的時間(間隔),通常是指從注冊(進入系統)到注銷(退出系統)之間所經過的時間。比如打電話時從拿起電話撥號到掛斷電話這中間的一系列過程可以稱之為一個Session。有時候我們可以看到這樣的話“在一個瀏覽器會話期間,…”,這里的會話一詞用的就是這個意思,是指從一個瀏覽器窗口打開到關閉這個期間。Session在我們的網絡應用中就是一種客戶端與服務器端保持狀態的解決方案,有時候Session也用來指這種解決方案的存儲結構,
Session對象,就是客戶端瀏覽器與服務器之間建立的互動信息狀態。每一個不同的用戶連接將得到不同的Session,也就是說Session與用戶之間是一種一對一的關系。Session在用戶進入網站時由服務器自動產生,並在用戶正常離開站點時釋放。使用Session的好處就在於,可以將很多與用戶相關的信息,例如用戶的帳號、昵稱等保存到Session中;利用Session,可以跟蹤用戶在網站上的活動。例如:當你上網進入一個網站時,如果你沒有登陸,無論你訪問哪幾個頁面都會跳轉回登陸頁。還有就是你在購物時,不可能把你的東西放到別人的購物車里去,這就得用一個信息變量來判斷!
如果能夠提供一些按需生成的動態信息會使web變得更加有用,就像給有線電視加上點播功能一樣。這種需求一方面迫使HTML逐步添加了表單、腳本、DOM 等客戶端行為,另一方面在服務器端則出現了CGI規范以響應客戶端的動態請求,作為傳輸載體的HTTP協議也添加了文件上載、cookie這些特性。其中 cookie的作用就是為了解決HTTP協議無狀態的缺陷所作出的努力。至於后來出現的Session機制則是又一種在客戶端與服務器之間保持狀態的解決方案。
二、Cookies
Cookie是WEB上最常用的跟蹤用戶會話方式,當 Cookie被禁止后,一般都用URL重寫來跟蹤會話。Cookie是一種由服務器發送給客戶的片段信息,存儲在客戶環境中,並在客戶所有的對服務器的請求中都要發回它。就好比我們在用IE登陸某個電子購物商城時,IE在得到商品列表頁面的 同時還收到Set-Cookie應答頭信息,我們打開一個Cookie文件,我們所看到的格式一般都是:
Cookie:NAME=VALUE;Comment=COMMENT;Domain=DOMAINNMAM;Max-age=SECONDS;Path=PATH;secure;Version=1*DIGIT
其中NAME值對(值對間用分號分隔)是必須的,其余都是可選的。最重要的信息當然也在所必須的值對里了,VALUE是NAME的值,也是這個 Cookie的標識,Max-age定義了Cookie的最長生存時間,其它幾個可選值對可參閱http://www.faqs.org/rfcs /rfc2109.html。當我們選購了某種商品,向服務器發送選購清單時,會自動在你的請求信息頭里加上NAME值對,如果Cookie被禁止,則用 URL重寫方式在URL請求地址上附加NAME值對。當Web服務器收到這個請求后,會檢查該Cookie是否存在,然后相應的跟蹤會話。從以上分析不難理解,其實Web服務器跟蹤會話就靠Set-Cookie頭信息,跟蹤NAME值對進行身份驗證。假如我們用非Web終端接收Web服務器的響應信息,從中解析出Cookie頭信息,當再次向Web服務器發送請求時附加上解析出的Cookie信息,Web服務器據此不就可以進行身份認證了嗎?
Cookies中文是餅干的意思,對於為何引用Cookies,從網上查找了一些資料:
在瀏覽器與WEB服務器之間是使用HTTP協議進行通信的,當某個用戶發出頁面請求時,WEB服務器只是簡單的進行響應,然后就關閉與該用戶的連接。因此當一個請求發送到WEB服務器時,無論其是否是第一次來訪,服務器都會把它當作第一次來對待,這樣的不好之處可想而知。為了彌補這個缺陷,Netscape開發出了cookie這個有效的工具來保存某個用戶的識別信息,因此人們昵稱為“小甜餅”。cookies是一種WEB服務器通過瀏覽器在訪問者的硬盤上存儲信息的手段:Netscape Navigator使用一個名為cookies.txt本地文件保存從所有站點接收的Cookie信息;而IE瀏覽器把Cookie信息保存在類似於 c:\Internet 臨時文件\的目錄下。當用戶再次訪問某個站點時,服務端將要求瀏覽器查找並返回先前發送的Cookie信息,來識別這個用戶。Cookies給網站和用戶帶來的好處:
(1)、Cookie能使站點跟蹤特定訪問者的訪問次數、最后訪問時間和訪問者進入站點的路徑
(2)、Cookie能告訴在線廣告商廣告被點擊的次數,從而可以更精確的投放廣告
(3)、Cookie有效期限未到時,Cookie能使用戶在不鍵入密碼和用戶名的情況下進入曾經瀏覽過的一些站點
(4)、Cookie能幫助站點統計用戶個人資料以實現各種各樣的個性化服務,其實,cookie的作用就是為了解決HTTP協議無狀態的缺陷所作的努力.
三.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應用程序開發者造成很大的困擾。
四、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機制與Session機制的區別和聯系
具體來說cookie機制采用的是在客戶端保持狀態的方案,而Session機制采用的是在服務器端保持狀態的方案。同時我們也看到,由於在服務器端保持狀態的方案在客戶端也需要保存一個標識,所以Session機制可能需要借助於cookie機制來達到保存標識的目的,但實際上還有其他選擇。例如,我們經常用到的會員卡,也就相當於這種情況。消費到了一定程度就有獎,就如下面例子說明:
1.發給顧客一張卡片,上面記錄着消費的數量,一般還有個有效期限。每次消費時,如果顧客出示這張卡片,則此次消費就會與以前或以后的消費相聯系起來。這種做法就是在客戶端保持狀態。
2、發給顧客一張會員卡,除了卡號之外什么信息也不紀錄,每次消費時,如果顧客出示該卡片,則店員在店里的紀錄本上找到這個卡號對應的紀錄添加一些消費信息。這種做法就是在服務器端保持狀態。
以下是一些關於兩者的區別與聯系:
具體來說cookie機制采用的是在客戶端保持狀態的方案。它是在用戶端的會話狀態的存貯機制,他需要用戶打開客戶端的cookie支持。cookie的作用就是為了解決HTTP協議無狀態的缺陷所作的努力.而Session機制采用的是一種在客戶端與服務器之間保持狀態的解決方案。同時我們也看到,由於采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以Session機制可能需要借助於cookie機制來達到保存標識的目的。而Session 提供了方便管理全局變量的方式。
Session是針對每一個用戶的,變量的值保存在服務器上,用一個Session來區分是哪個用戶Session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置為由get來返回給服務器。
就安全性來說:當你訪問一個使用Session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的SESSION機制更安全些.因為它不會任意讀取客戶存儲的信息。
正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。
從網絡服務器觀點看所有HTTP請求都獨立於先前請求。就是說每一個HTTP響應完全依賴於相應請求中包含的信息.
狀態管理機制克服了HTTP的一些限制並允許網絡客戶端及服務器端維護請求間的關系。在這種關系維持的期間叫做會話(Session)。
Cookies是服務器在本地機器上存儲的小段文本並隨每一個請求發送至同一個服務器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie規范。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies並將它們保存為一個本地文件,它會自動將同一服務器的任何請求縛上這些cookies 。
來看一下Tomcat是如何實現web應用程序之間session的隔離的,從Tomcat設置的cookie路徑來看,它對不同的應用程序設置的 cookie路徑是不同的,這樣不同的應用程序所用的session id是不同的,因此即使在同一個瀏覽器窗口里訪問不同的應用程序,發送給服務器的session id也可以是不同的。
六、常見問題
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的超時有什么區別
會話的超時由服務器來維護,它不同於Cookie的失效日期。首先,會話一般基於駐留內存的cookie不是持續性的cookie,因而也就沒有截至日期。即使截取到JSESSION cookie,並為它設定一個失效日期發送出去。瀏覽器會話和服務器會話也會截然不同。
七、Session的用法
Session 對象
可以使用 Session 對象存儲特定用戶會話所需的信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。
當用戶請求來自應用程序的 Web 頁時,如果該用戶還沒有會話,則 Web 服務器將自動創建一個 Session 對象。當會話過期或被放棄后,服務器將終止該會話。
Session 對象最常見的一個用法就是存儲用戶的首選項。例如,如果用戶指明不喜歡查看圖形,就可以將該信息存儲在 Session 對象中。
注意:會話狀態僅在支持 cookie 的瀏覽器中保留。
語法
Session.collection|property|method
集合
Contents 包含已用腳本命令添加到會話中的項目。
StaticObjects 包含通過 <OBJECT> 標記創建的並給定了會話作用域的對象。
屬性
CodePage 將用於符號映射的代碼頁。
LCID 現場標識。
SessionID 返回用戶的會話驗證。
Timeout 應用程序會話狀態的超時時限,以分鍾為單位。
方法
Abandon 該方法破壞 Session 對象並釋放其資源。
事件
asa 文件中聲明下列事件的腳本。
Session_OnEnd
Session_OnStart
注釋
您可以在 Session 對象中存儲值。存儲在 Session 對象中的信息在會話及會話作用域內有效。