天天看點

【轉】WEB應用中的SESSION知多少?

作為一名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,可以跟蹤使用者在網站上的活動。例如:當你上網進入一個網站時,如果你沒有登陸,無論你通路哪幾個頁面都會跳轉回登陸頁。還有就是你在購物時,不可能把你的東西放到别人的購物車裡去,這就得用一個資訊變量來判斷! 

如果能夠提供一些按需生成的動态資訊會使web變得更加有用,就像給有線電視加上點播功能一樣。這種需求一方面迫使html逐漸添加了表單、腳本、dom等用戶端行為,另一方面在伺服器端則出現了cgi規範以響應用戶端的動态請求,作為傳輸載體的http協定也添加了檔案上載、cookie這些特性。其中cookie的作用就是為了解決http協定無狀态的缺陷所作出的努力。至于後來出現的session機制則是又一種在用戶端與伺服器之間保持狀态的解決方案。

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仍然有效直到超過設定的過期時間。 

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會丢掉嗎 

10、cookie的過期和session的逾時有什麼差別 

會話的逾時由伺服器來維護,它不同于cookie的失效日期。首先,會話一般基于駐留記憶體的cookie不是持續性的cookie,因而也就沒有截至日期。即使截取到jsession cookie,并為它設定一個失效日期發送出去。浏覽器會話和伺服器會話也會截然不同。 

轉載位址:http://www.blogjava.net/ohyeah928/archive/2010/01/27/310952.html