前言
Session 作用并存活于服務(wù)端此疹,Cookie 被用戶留在了本地設(shè)備中(客戶端)。Cookie 目的可以跟蹤會(huì)話,也可以保存用戶喜好或者保存用戶名密碼舔亭;
Session 用來跟蹤會(huì)話些膨。這是首先需要知道的一點(diǎn),然后我們先來詳細(xì)聊聊這兩個(gè)家伙吧钦铺。
Session
Session: 在計(jì)算機(jī)中订雾,尤其是在網(wǎng)絡(luò)應(yīng)用中,稱為“會(huì)話控制”矛洞。Session 對象存儲(chǔ)特定用戶會(huì)話所需的屬性及配置信息洼哎。這樣,當(dāng)用戶在應(yīng)用程序的 Web 頁之間跳轉(zhuǎn)時(shí)沼本,存儲(chǔ)在 Session 對象中的變量將不會(huì)丟失噩峦,而是在整個(gè)用戶會(huì)話中一直存在下去。當(dāng)用戶請求來自應(yīng)用程序的 Web 頁時(shí)抽兆,如果該用戶還沒有會(huì)話识补,則 Web 服務(wù)器將自動(dòng)創(chuàng)建一個(gè) Session 對象。當(dāng)會(huì)話過期或被放棄后辫红,服務(wù)器將終止該會(huì)話凭涂。Session 對象最常見的一個(gè)用法就是存儲(chǔ)用戶的首選項(xiàng)。例如贴妻,如果用戶指明不喜歡查看圖形切油,就可以將該信息存儲(chǔ)在 Session 對象中。有關(guān)使用 Session 對象的詳細(xì)信息揍瑟,請參閱“ASP 應(yīng)用程序”部分的“管理會(huì)話”白翻。注意 會(huì)話狀態(tài)僅在支持 cookie 的瀏覽器中保留。
Cookie
Cookie绢片,有時(shí)也用其復(fù)數(shù)形式 Cookies滤馍,指某些網(wǎng)站為了辨別用戶身份、進(jìn)行 session 跟蹤而儲(chǔ)存在用戶本地終端上的數(shù)據(jù)(通常經(jīng)過加密)底循。定義于 RFC2109 和 2965 中的都已廢棄巢株,最新取代的規(guī)范是 RFC6265。(可以叫做瀏覽器緩存)
Cookie 在計(jì)算機(jī)中是個(gè)存儲(chǔ)在瀏覽器目錄中的文本文件熙涤,當(dāng)瀏覽器運(yùn)行時(shí)阁苞,存儲(chǔ)在 RAM 中發(fā)揮作用 (此種 Cookies 稱作 Session Cookies),一旦用戶從該網(wǎng)站或服務(wù)器退出祠挫,Cookie 可存儲(chǔ)在用戶本地的硬盤上 (此種 Cookies 稱作 Persistent Cookies)那槽。
通常情況下,當(dāng)用戶結(jié)束瀏覽器會(huì)話時(shí)等舔,系統(tǒng)將終止所有的 Cookie骚灸。當(dāng) Web 服務(wù)器創(chuàng)建了Cookies 后,只要在其有效期內(nèi)慌植,當(dāng)用戶訪問同一個(gè) Web 服務(wù)器時(shí)甚牲,瀏覽器首先要檢查本地的Cookies义郑,并將其原樣發(fā)送給 Web 服務(wù)器。這種狀態(tài)信息稱作“Persistent Client State HTTP Cookie” 丈钙,簡稱為 Cookies 非驮。
區(qū)別
- 由于 HTTP 協(xié)議是無狀態(tài)的協(xié)議,所以服務(wù)端需要記錄用戶的狀態(tài)時(shí)雏赦,就需要用某種機(jī)制來識具體的用戶劫笙,這個(gè)機(jī)制就是 Session。典型的場景比如購物車喉誊,當(dāng)你點(diǎn)擊下單按鈕時(shí)邀摆,由于 HTTP 協(xié)議無狀態(tài),所以并不知道是哪個(gè)用戶操作的伍茄,所以服務(wù)端要為特定的用戶創(chuàng)建了特定的 Session栋盹,用用于標(biāo)識這個(gè)用戶,并且跟蹤用戶敷矫,這樣才知道購物車?yán)锩嬗袔妆緯瘛_@個(gè) Session 是保存在服務(wù)端的,有一個(gè)唯一標(biāo)識曹仗。在服務(wù)端保存 Session 的方法很多榨汤,內(nèi)存、數(shù)據(jù)庫怎茫、文件都有收壕。集群的時(shí)候也要考慮 Session 的轉(zhuǎn)移,在大型的網(wǎng)站轨蛤,一般會(huì)有專門的 Session 服務(wù)器集群蜜宪,用來保存用戶會(huì)話,這個(gè)時(shí)候 Session 信息都是放在內(nèi)存的祥山,使用一些緩存服務(wù)比如 Memcached 之類的來放 Session圃验。
- 思考一下服務(wù)端如何識別特定的客戶?這個(gè)時(shí)候 Cookie 就登場了缝呕。每次 HTTP 請求的時(shí)候澳窑,客戶端都會(huì)發(fā)送相應(yīng)的 Cookie 信息(保障在 Request Header 中)到服務(wù)端。實(shí)際上大多數(shù)的應(yīng)用都是用 Cookie 來實(shí)現(xiàn) Session 跟蹤的供常,第一次創(chuàng)建 Session 的時(shí)候摊聋,服務(wù)端會(huì)在 HTTP 協(xié)議中告訴客戶端,需要在 Cookie 里面記錄一個(gè) Session ID栈暇,以后每次請求把這個(gè)會(huì)話 ID 發(fā)送到服務(wù)器栗精,我就知道你是誰了。有人問,如果客戶端的瀏覽器禁用了 Cookie 怎么辦悲立?一般這種情況下,會(huì)使用一種叫做 URL 重寫的技術(shù)來進(jìn)行會(huì)話跟蹤新博,即每次 HTTP 交互薪夕,URL 后面都會(huì)被附加上一個(gè)諸如 sid=xxxxx 這樣的參數(shù),服務(wù)端據(jù)此來識別用戶赫悄。
- Cookie 其實(shí)還可以用在一些方便用戶的場景下原献,設(shè)想你某次登陸過一個(gè)網(wǎng)站,下次登錄的時(shí)候不想再次輸入賬號了埂淮,怎么辦姑隅?這個(gè)信息可以寫到 Cookie 里面,訪問網(wǎng)站的時(shí)候倔撞,網(wǎng)站頁面的腳本可以讀取這個(gè)信息讲仰,就自動(dòng)幫你把用戶名給填了,能夠方便一下用戶痪蝇。這也是 Cookie 名稱(譯名:小甜點(diǎn))的由來鄙陡,給用戶的一點(diǎn)甜頭。
總結(jié)
- Session 在服務(wù)器端躏啰,Cookie 在客戶端(瀏覽器)
- Session 默認(rèn)被存在在服務(wù)器的一個(gè)文件里
- Session 的運(yùn)行依賴 session id趁矾,而 session id 是存在 Cookie 中的,也就是說给僵,如果瀏覽器禁用了 Cookie 毫捣,同時(shí) session 也會(huì)失效(但是可以通過其它方式實(shí)現(xiàn),比如在 url 中傳遞 session_id)
- Session 可以放在 文件帝际、數(shù)據(jù)庫蔓同、或內(nèi)存中都可以。
- 用戶驗(yàn)證這種場合一般會(huì)用 Session
因此胡本,維持一個(gè)會(huì)話的核心就是客戶端的唯一標(biāo)識牌柄,即 session id
One More Thine
使用 Tomcat 等中間件的小伙伴們可能遇到過這樣的情況(或者還沒遇到過,也請注意一下)
關(guān)閉 Tomcat 后進(jìn)行重啟侧甫,之后再次獲取 Session珊佣,居然拿到了關(guān)閉前的 Session,為什么呢披粟,應(yīng)該被 Tomcat 清理了爸涠汀?
其實(shí)是守屉,Tomcat 在每次關(guān)閉的時(shí)候惑艇,都會(huì)將當(dāng)前每個(gè) Session 中的內(nèi)容寫到文件中,然后重新啟動(dòng) Tomcat 的時(shí)候讀取這個(gè)文件,并且驗(yàn)證 Session 是否超時(shí)滨巴,沒有超時(shí)就記錄了這個(gè)有效的 Session思灌。所以解決辦法也公布出來:
和 Tomcat 的配置有關(guān)系: tomcat/conf/context.xml 配置中:
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
取消注釋就好了。