Session與Cookie的區別
Session與Cookie的區別zhuan(http://www.imtinewlife.com/BBS/ShowPost.asp?ThreadID=2768)
為什么會有cookie呢,大家都知道,http是無狀態的協議,客戶每次讀取
web頁面時,服務器都打開新的會話,而且服務器也不會自動維護客戶的上下文信息,那么要怎么才能實現網上商店中的購物車呢,session就是一種保存
上下文信息的機制,它是針對每一個用戶的,變量的值保存在服務器端,通過
SessionID來區分不同的客戶,session是以cookie或URL重寫為基礎的,默認使用cookie來實現,系統會創造一個名為
JSESSIONID的輸出cookie,我們叫做session cookie,以區別persistent
cookies,也就是我們通常所說的cookie,注意session
cookie是存儲于瀏覽器內存中的,并不是寫到硬盤上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但
是當我們把瀏覽器的cookie禁止后,WEB服務器會采用URL重寫的方式傳遞Sessionid,我們就可以在地址欄看到sessionid=
KWJHUG6JJM65HS2K6之類的字符串。
明白了原理,我們就可以很容易的分辨出persistent cookies和session
cookie的區別了,網上那些關于兩者安全性的討論也就一目了然了,session
cookie針對某一次會話而言,會話結束session cookie也就隨著消失了,而persistent
cookie只是存在于客戶端硬盤上的一段文本(通常是加密的),而且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,自然不如
session cookie安全了。
通常session
cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣我們信息共享的目的就達不到
了,此時我們可以先把sessionid保存在persistent
cookie中,然后在新窗口中讀出來,就可以得到上一個窗口SessionID了,這樣通過session
cookie和persistent cookie的結合我們就實現了跨窗口的session tracking(會話跟蹤)。
在一些WEB開發的書中,往往只是簡單的把Session和cookie作為兩種并列的http傳送信息的方式,session
cookies位于服務器端,persistent
cookie位于客戶端,可是session又是以cookie為基礎的,明白的兩者之間的聯系和區別,我們就不難選擇合適的技術來開發WEB
service了。
(1)
session總是放在服務器上的,每個客戶會跟一個sessionID對應。因為HTTP是無連接的,如何區分同一個客戶的多次請求呢,就需要客戶端每次發請求的時候,發送相應的sessionID。
通常情況下,sessionID在客戶端以cookie的形式保存。如果瀏覽器靜止了cookie,客戶端再向服務器發請求的時候,就不會發送sessionID,因此服務器就會將這個請求作為一個新客戶,所以就會出現session值丟失的假象。
這
時候出現一個問題,如果客戶瀏覽器不支持cookie,怎么辦?J2EE提供的另一個辦法就是URL重寫,寫超鏈接的時侯,總是用
response.encodeURL(url),連接就會變成*.jsp?sessionID=......,完成了原來用cookie完成的功能。
J2EE建議,不論客戶瀏覽器是否支持cookie,服務器端編程都建議使用URL重寫。
(2)
web上用的都是非連接的網絡協議
session 是存在服務器上的
每個session有一個唯一的session ID(為了標識他是那個客戶端的)
在啟動session的同時,會在客戶端生成cookie,服務器把session ID加到cookie中
每次服務器和客戶端交互的時候,就是從cookie中取得session ID 來定位服務器上的session
這樣只要你的cookie不過期,服務器上有你的session,就不會出問題
(3)
JSP實現在瀏覽器關閉cookies情況下的會話管理
通常,會話管理是通過服務器將 Session ID 作為一個 cookie 存儲在用戶的 Web 瀏覽器中來唯一標識每個用戶會話。如果瀏覽器不支持 cookies,或者將瀏覽器設置為不接受 cookies,我們可以通過 URL 重寫來實現會話管理。
實質上 URL 重寫是通過向 URL 連接添加參數,并把 session ID 作為值包含在連接中。然而,為使這生效,你需要為你的 servlet 響應部分的每個連接添加 session ID 。
把 session ID 加到一個連接可以使用一對方法來簡化:response.encodeURL() 使 URL 包含 session ID,如果你需要使用重定向,可以使用 response.encodeRedirectURL () 來對 URL 進行編碼。
encodeURL () 及 encodeRedirectedURL () 方法首先判斷 cookies 是否被瀏覽器支持;如果支持,則參數 URL 被原樣返回,session ID 將通過 cookies 來維持。
來看下面的例子,兩個 JSP 文件:hello1.jsp 和 hello2.jsp,及它們之間的影響。我們在 hello1.jsp 中簡單的創建一個會話,并在 session 中存儲一個對象實例。接著用戶可以點擊頁面的連接到達 hello2.jsp。在 hello2.jsp 中,我們從 session 中獲取原先放置的對象并顯示它的內容。注意,我們在 hello1.jsp 中調用了 encodeURL() 方法來獲得 hello2.jsp 的鏈接,使得在瀏覽器停用 cookies 的情況下,session ID 自動添加到 URL,hello2.jsp 仍能得到 session 對象。
首先在啟用 cookies 的情況下運行。然后關閉對 cookie 的支持,重啟瀏覽器,再運行一次。每次你都可以看到會話管理在起作用,并能在頁之間傳遞信息。
注意,如果你想讓這個例子能在關閉了 cookies 的瀏覽器中工作,你的 JSP 引擎必須支持 URL 重寫。
---------------------------------------------------------------------------------------------------------------------------------------
cookie 機制。正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的 cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則 在后臺自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用范圍大于等于將要請求的資源所在的位置,則把該 cookie附在請求資源的HTTP請求頭上發送給服務器。
cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一 起構成cookie的作用范圍。若不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期為 瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存里,當然這種行為并不是規范規定的。若設置了過期 時間,瀏覽器就會把cookie保存到硬盤上,關閉后再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。存儲在硬盤上的cookie可以 在不同的瀏覽器進程間共享,比如兩個IE窗口。而對于保存在內存里的cookie,不同的瀏覽器有不同的處理方式
session機制。session機制是一種服務器端的機制,服務器使用一種類似于散列表的結構(也可能就是使用散列表)來保存信息。
當 程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識(稱為 sessionid),如果已包含則說明以前已經為此客戶端創建過session,服務器就按照sessionid把這個session檢索出來使用(檢 索不到,會新建一個),如果客戶端請求不包含sessionid,則為此客戶端創建一個session并且生成一個與此session相關聯的 session id,sessionid的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
保存這個sessionid的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照 規則把這個標識發揮給服務器。一般這個cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在 cookie被禁止時仍然能夠把sessionid傳遞回服務器。
經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把sessionid傳遞回服務器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid"
value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
實際上這種技術可以簡單的用對action應用URL重寫來代替。