session 跟cookie有是一對好基友欣孤。它們誕生與HTTP協(xié)議有一定的歷史關(guān)系郎任。
簡單來說史翘,session與cookie是為了滿足HTTP協(xié)議1.1所不能滿足需求颖医,應(yīng)運(yùn)而生位衩。但是這對好基友卻不是協(xié)議層面的實(shí)事物,他們從本質(zhì)上熔萧,是對HTTP協(xié)議的一種擴(kuò)展
HTTP協(xié)議是無狀態(tài)的糖驴,而session與cookie則是分別從服務(wù)器端與客戶端去維護(hù)訪問狀態(tài)。
舉個(gè)例子佛致,今天你登錄某網(wǎng)站贮缕,然后關(guān)了電腦,第二天開機(jī)晌杰,再次登錄該網(wǎng)站跷睦,發(fā)現(xiàn)不需要再次輸入用戶名和密碼。這是由于cookie在客戶端保存了你的登陸信息或者說賬戶資料肋演,并且該cookie對應(yīng)于服務(wù)端擁有唯一標(biāo)識的session,session保存了賬戶的訪問狀態(tài)烂琴,所以用戶登陸后cookie會隨著訪問請求一起發(fā)送往服務(wù)端爹殊,服務(wù)端由此可以將用戶當(dāng)做已登陸來識別。而這個(gè)訪問狀態(tài)顯然就是指數(shù)據(jù)(用戶名或者密碼之類的)奸绷。
cookie:
無論使用何種服務(wù)端技術(shù)梗夸,只要發(fā)送回的HTTP響應(yīng)中包含如下形式的頭,則視為服務(wù)器要求設(shè)置一個(gè)cookie:
Set-cookie:name=name;expires=date;path=path;domain=domain
支持cookie的瀏覽器都會對此作出反應(yīng)号醉,即創(chuàng)建cookie文件并保存(也可能是內(nèi)存cookie)反症,用戶以后在每次發(fā)出請求時(shí),瀏覽器都要判斷當(dāng)前所有的cookie中有沒有沒失效(根據(jù)expires屬性判斷)并且匹配了path屬性的cookie信息畔派,如果有的話铅碍,會以下面的形式加入到請求頭中發(fā)回服務(wù)端:
Cookie: name="zj"; Path="/linkage"
服務(wù)端的動態(tài)腳本會對其進(jìn)行分析,并做出相應(yīng)的處理线椰,當(dāng)然也可以選擇直接忽略胞谈。需要注意的是,出于安全性的考慮,cookie可以被瀏覽器禁用烦绳。
session:
它的基本原理是服務(wù)端為每一個(gè)session維護(hù)一份會話信息數(shù)據(jù)卿捎,而客戶端和服務(wù)端依靠一個(gè)全局唯一的標(biāo)識來訪問會話信息數(shù)據(jù)。用戶訪問web應(yīng)用時(shí)径密,服務(wù)端程序決定何時(shí)創(chuàng)建session午阵,創(chuàng)建session可以概括為三個(gè)步驟:
1.? ?生成全局唯一標(biāo)識符(sessionid)。
2.???開辟數(shù)據(jù)存儲空間享扔。一般會在內(nèi)存中創(chuàng)建相應(yīng)的數(shù)據(jù)結(jié)構(gòu)趟庄。但是!這種情況下伪很,系統(tǒng)一旦斷電戚啥,所有的會話數(shù)據(jù)就會丟失,如果是電子商務(wù)網(wǎng)站锉试,這種事故會造成嚴(yán)重的后果猫十。不過也可以寫到文件里甚至存儲在數(shù)據(jù)庫中,這樣雖然會增加I/O開銷呆盖,但session可以實(shí)現(xiàn)某種程度的持久化拖云,而且更有利于session的共享。
3.? ?將sessionid發(fā)送給客戶端应又。而發(fā)送sessionid又有兩種方式:cookie和URL重寫
? ? ? cookie:服務(wù)端只要設(shè)置Set-cookie頭就可以將session的標(biāo)識符傳送到客戶端宙项,而客戶端此后的每一次請求都會帶上這個(gè)標(biāo)識符,由于cookie可以設(shè)置失效時(shí)間株扛,所以一般包含session信息的cookie會設(shè)置失效時(shí)間為0尤筐,即瀏覽器進(jìn)程有效時(shí)間。至于瀏覽器怎么處理這個(gè)0洞就,每個(gè)瀏覽器都有自己的方案盆繁,但差別都不會太大(一般體現(xiàn)在新建瀏覽器窗口的時(shí)候)
? ? ? URL重寫:就如字面意思那樣。在返回用戶請求的頁面之前旬蟋,將頁面內(nèi)所有的URL后面全部以get參數(shù)的方式加上session標(biāo)識符油昂,這樣用戶在收到響應(yīng)之后,無論點(diǎn)擊哪個(gè)鏈接或提交表單倾贰,都會在再帶上session的標(biāo)識符冕碟,從而就實(shí)現(xiàn)了會話的保持。
如果客戶端禁用了cookie的話匆浙,URL重寫將會是首選安寺。
那么這整個(gè)過程是怎樣的呢?
當(dāng)你訪問某網(wǎng)址的時(shí)候吞彤,服務(wù)器返回的響應(yīng)頭里會有Set-cookie ?JSESSIONID="xx";Path="xx";name="xx";expires="xx";domain="xx";name="xx";
這個(gè)JSESSIONID里面的就是sessionid了我衬,這就是服務(wù)器創(chuàng)建了seesion叹放,記錄了訪問狀態(tài),并且告訴客戶端瀏覽器以sessionid為唯一標(biāo)示符挠羔,創(chuàng)建cookie井仰。并且每次發(fā)出請求前都要去匹配所有cookie的Path屬性,將相匹配的cookie以下面這種形式發(fā)送到服務(wù)端:
Cookie: JSESSIONID="xx";name="xx"; Path="xx";
服務(wù)端在識別cookie中的sessionid后會在服務(wù)端調(diào)用匹配的session對訪問請求進(jìn)行處理破加,再次返回的響應(yīng)里就不會帶有涉及session或者cookie的信息俱恶。
cookie和session都有可以設(shè)置有效期,一般來說session中默認(rèn)有效期都是短時(shí)效的范舀,例如Tomcat中Session的默認(rèn)失效時(shí)間為30分鐘合是,cookie的有效期。當(dāng)然锭环,也可以在有效期期間清除session或cookie聪全,如手動清除cookie或session,關(guān)閉瀏覽器后引發(fā)session超時(shí)等辅辩。
有關(guān)session的手動銷毀难礼,這里有個(gè)小知識。當(dāng)服務(wù)端銷毀session后玫锋,客戶端依舊發(fā)送cookie蛾茉,這時(shí)服務(wù)端在找不到匹配的sessionid的情況下會重新創(chuàng)建新的session,并告知客戶端更新sessionid開始保持新的會話撩鹿。
我們再來看看session與cookie在其他方面的對比:
安全性
cookie將信息保存在客戶端谦炬,如果不進(jìn)行加密的話,安全性很差节沦,即使加密也很容易就會被竊取键思。而session只會將信息存儲在服務(wù)端,如果存儲在文件或數(shù)據(jù)庫中散劫,也有被竊取的可能稚机。session安全性方面比較突出的是存在會話劫持的問題,當(dāng)sessionid被盜用获搏,由于HTTP協(xié)議的無狀態(tài)性,服務(wù)器無法得知session是否被劫持失乾,但總的來講安全性要高于cookie常熙。
大小限制
Cookie的處理在開發(fā)中沒有session方便。而且cookie在客戶端是有數(shù)量和大小的限制的碱茁,而session的大小只以硬件為限制裸卫,能存儲的數(shù)據(jù)大了很多。