Cookies和Session的區(qū)別和理解
官方理解:
cookie機(jī)制
Cookies是服務(wù)器在本地機(jī)器上存儲(chǔ)的小段文本并隨每一個(gè)請(qǐng)求發(fā)送至同一個(gè)服務(wù)器。IETF RFC 2965 HTTP State Management Mechanism 是通用cookie規(guī)范。網(wǎng)絡(luò)服務(wù)器用HTTP頭向客戶端發(fā)送cookies,在客戶終端,瀏覽器解析這些cookies并將它們保存為一個(gè)本地文件,它會(huì)自動(dòng)將同一服務(wù)器的任何請(qǐng)求縛上這些cookies 。
具體來(lái)說(shuō)cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案。它是在用戶端的會(huì)話狀態(tài)的存貯機(jī)制,他需要用戶打開客戶端的cookie支持。cookie的作用就是為了解決HTTP協(xié)議無(wú)狀態(tài)的缺陷所作的努力。
正統(tǒng)的cookie分發(fā)是通過(guò)擴(kuò)展HTTP協(xié)議來(lái)實(shí)現(xiàn)的,服務(wù)器通過(guò)在HTTP的響應(yīng)頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應(yīng)的cookie。然而純粹的客戶端腳本如JavaScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則在后臺(tái)自動(dòng)發(fā)送給服務(wù)器的。瀏覽器檢查所有存儲(chǔ)的cookie,如果某個(gè)cookie所聲明的作用范圍大于等于將要請(qǐng)求的資源所在的位置,則把該cookie附在請(qǐng)求資源的HTTP請(qǐng)求頭上發(fā)送給服務(wù)器。
cookie的內(nèi)容主要包括:名字,值,過(guò)期時(shí)間,路徑和域。路徑與域一起構(gòu)成cookie的作用范圍。若不設(shè)置過(guò)期時(shí)間,則表示這個(gè)cookie的生命期為瀏覽器會(huì)話期間,關(guān)閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會(huì)話期的cookie被稱為會(huì)話cookie。會(huì)話cookie一般不存儲(chǔ)在硬盤上而是保存在內(nèi)存里,當(dāng)然這種行為并不是規(guī)范規(guī)定的。若設(shè)置了過(guò)期時(shí)間,瀏覽器就會(huì)把cookie保存到硬盤上,關(guān)閉后再次打開瀏覽器,這些cookie仍然有效直到超過(guò)設(shè)定的過(guò)期時(shí)間。存儲(chǔ)在硬盤上的cookie可以在不同的瀏覽器進(jìn)程間共享,比如兩個(gè)IE窗口。而對(duì)于保存在內(nèi)存里的cookie,不同的瀏覽器有不同的處理方式。
而session機(jī)制采用的是一種在服務(wù)器端保持狀態(tài)的解決方案。同時(shí)我們也看到,由于采用服務(wù)器端保持狀態(tài)的方案在客戶端也需要保存一個(gè)標(biāo)識(shí),所以session機(jī)制可能需要借助于cookie機(jī)制來(lái)達(dá)到保存標(biāo)識(shí)的目的。而session提供了方便管理全局變量的方式 。
session是針對(duì)每一個(gè)用戶的,變量的值保存在服務(wù)器上,用一個(gè)sessionID來(lái)區(qū)分是哪個(gè)用戶session變量,這個(gè)值是通過(guò)用戶的瀏覽器在訪問(wèn)的時(shí)候返回給服務(wù)器,當(dāng)客戶禁用cookie時(shí),這個(gè)值也可能設(shè)置為由get來(lái)返回給服務(wù)器。
就安全性來(lái)說(shuō):當(dāng)你訪問(wèn)一個(gè)使用session 的站點(diǎn),同時(shí)在自己機(jī)子上建立一個(gè)cookie,建議在服務(wù)器端的session機(jī)制更安全些,因?yàn)樗粫?huì)任意讀取客戶存儲(chǔ)的信息。
SESSION機(jī)制
session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來(lái)保存信息。
當(dāng)程序需要為某個(gè)客戶端的請(qǐng)求創(chuàng)建一個(gè)session時(shí),服務(wù)器首先檢查這個(gè)客戶端的請(qǐng)求里是否已包含了一個(gè)session標(biāo)識(shí)(稱為session id),如果已包含則說(shuō)明以前已經(jīng)為此客戶端創(chuàng)建過(guò)session,服務(wù)器就按照session id把這個(gè)session檢索出來(lái)使用(檢索不到,會(huì)新建一個(gè)),如果客戶端請(qǐng)求不包含session id,則為此客戶端創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的session id,session id的值應(yīng)該是一個(gè)既不會(huì)重復(fù),又不容易被找到規(guī)律以仿造的字符串,這個(gè)session id將被在本次響應(yīng)中返回給客戶端保存。
保存這個(gè)session id的方式可以采用cookie,這樣在交互過(guò)程中瀏覽器可以自動(dòng)的按照規(guī)則把這個(gè)標(biāo)識(shí)發(fā)揮給服務(wù)器。一般這個(gè)cookie的名字都是類似于SEEESIONID。但cookie可以被人為的禁止,則必須有其他機(jī)制以便在cookie被禁止時(shí)仍然能夠把session id傳遞回服務(wù)器。
經(jīng)常被使用的一種技術(shù)叫做URL重寫,就是把session id直接附加在URL路徑的后面。還有一種技術(shù)叫做表單隱藏字段。就是服務(wù)器會(huì)自動(dòng)修改表單,添加一個(gè)隱藏字段,以便在表單提交時(shí)能夠把session id傳遞回服務(wù)器。
Cookie與Session都能夠進(jìn)行會(huì)話跟蹤,但是完成的原理不太一樣。普通狀況下二者均能夠滿足需求,但有時(shí)分不能夠運(yùn)用Cookie,有時(shí)分不能夠運(yùn)用Session。下面經(jīng)過(guò)比擬闡明二者的特性以及適用的場(chǎng)所。
1 .存取方式的不同
Cookie中只能保管ASCII字符串,假如需求存取Unicode字符或者二進(jìn)制數(shù)據(jù),需求先進(jìn)行編碼。Cookie中也不能直接存取Java對(duì)象。若要存儲(chǔ)略微復(fù)雜的信息,運(yùn)用Cookie是比擬艱難的。
而Session中能夠存取任何類型的數(shù)據(jù),包括而不限于String、Integer、List、Map等。Session中也能夠直接保管Java Bean乃至任何Java類,對(duì)象等,運(yùn)用起來(lái)十分便當(dāng)。能夠把Session看做是一個(gè)Java容器類。
2 .隱私策略的不同
Cookie存儲(chǔ)在客戶端閱讀器中,對(duì)客戶端是可見的,客戶端的一些程序可能會(huì)窺探、復(fù)制以至修正Cookie中的內(nèi)容。而Session存儲(chǔ)在服務(wù)器上,對(duì)客戶端是透明的,不存在敏感信息泄露的風(fēng)險(xiǎn)。
假如選用Cookie,比較好的方法是,敏感的信息如賬號(hào)密碼等盡量不要寫到Cookie中。***是像Google、Baidu那樣將Cookie信息加密,提交到服務(wù)器后再進(jìn)行解密,保證Cookie中的信息只要本人能讀得懂。而假如選擇Session就省事多了,反正是放在服務(wù)器上,Session里任何隱私都能夠有效的保護(hù)。
3.有效期上的不同
使用過(guò)Google的人都曉得,假如登錄過(guò)Google,則Google的登錄信息長(zhǎng)期有效。用戶不用每次訪問(wèn)都重新登錄,Google會(huì)持久地記載該用戶的登錄信息。要到達(dá)這種效果,運(yùn)用Cookie會(huì)是比較好的選擇。只需要設(shè)置Cookie的過(guò)期時(shí)間屬性為一個(gè)很大很大的數(shù)字。
由于Session依賴于名為JSESSIONID的Cookie,而Cookie JSESSIONID的過(guò)期時(shí)間默許為–1,只需關(guān)閉了閱讀器該Session就會(huì)失效,因而Session不能完成信息永世有效的效果。運(yùn)用URL地址重寫也不能完成。而且假如設(shè)置Session的超時(shí)時(shí)間過(guò)長(zhǎng),服務(wù)器累計(jì)的Session就會(huì)越多,越容易招致內(nèi)存溢出。
4.服務(wù)器壓力的不同
Session是保管在服務(wù)器端的,每個(gè)用戶都會(huì)產(chǎn)生一個(gè)Session。假如并發(fā)訪問(wèn)的用戶十分多,會(huì)產(chǎn)生十分多的Session,耗費(fèi)大量的內(nèi)存。因而像Google、Baidu、Sina這樣并發(fā)訪問(wèn)量極高的網(wǎng)站,是不太可能運(yùn)用Session來(lái)追蹤客戶會(huì)話的。
而Cookie保管在客戶端,不占用服務(wù)器資源。假如并發(fā)閱讀的用戶十分多,Cookie是很好的選擇。關(guān)于Google、Baidu、Sina來(lái)說(shuō),Cookie或許是唯一的選擇。
5 .瀏覽器支持的不同
Cookie是需要客戶端瀏覽器支持的。假如客戶端禁用了Cookie,或者不支持Cookie,則會(huì)話跟蹤會(huì)失效。關(guān)于WAP上的應(yīng)用,常規(guī)的Cookie就派不上用場(chǎng)了。
假如客戶端瀏覽器不支持Cookie,需要運(yùn)用Session以及URL地址重寫。需要注意的是一切的用到Session程序的URL都要進(jìn)行URL地址重寫,否則Session會(huì)話跟蹤還會(huì)失效。關(guān)于WAP應(yīng)用來(lái)說(shuō),Session+URL地址重寫或許是它唯一的選擇。
假如客戶端支持Cookie,則Cookie既能夠設(shè)為本瀏覽器窗口以及子窗口內(nèi)有效(把過(guò)期時(shí)間設(shè)為–1),也能夠設(shè)為一切閱讀器窗口內(nèi)有效(把過(guò)期時(shí)間設(shè)為某個(gè)大于0的整數(shù))。但Session只能在本閱讀器窗口以及其子窗口內(nèi)有效。假如兩個(gè)瀏覽器窗口互不相干,它們將運(yùn)用兩個(gè)不同的Session。(IE8下不同窗口Session相干)
6.跨域支持上的不同
Cookie支持跨域名訪問(wèn),例如將domain屬性設(shè)置為“.biaodianfu.com”,則以“.biaodianfu.com”為后綴的一切域名均能夠訪問(wèn)該Cookie。跨域名Cookie如今被普遍用在網(wǎng)絡(luò)中,例如Google、Baidu、Sina等。而Session則不會(huì)支持跨域名訪問(wèn)。Session僅在他所在的域名內(nèi)有效。
僅運(yùn)用Cookie或者僅運(yùn)用Session可能完成不了理想的效果。這時(shí)應(yīng)該嘗試一下同時(shí)運(yùn)用Cookie與Session。Cookie與Session的搭配運(yùn)用在實(shí)踐項(xiàng)目中會(huì)完成很多意想不到的效果。
我的理解:
1. 由于HTTP協(xié)議是無(wú)狀態(tài)的協(xié)議,所以服務(wù)端需要記錄用戶的狀態(tài)時(shí),就需要用某種機(jī)制來(lái)識(shí)具體的用戶,這個(gè)機(jī)制就是Session.典型的場(chǎng)景比如購(gòu)物車,當(dāng)你點(diǎn)擊下單按鈕時(shí),由于HTTP協(xié)議無(wú)狀態(tài),所以并不知道是哪個(gè)用戶操作的,所以服務(wù)端要為特定的用戶創(chuàng)建了特定的Session,用用于標(biāo)識(shí)這個(gè)用戶,并且跟蹤用戶,這樣才知道購(gòu)物車?yán)锩嬗袔妆緯_@個(gè)Session是保存在服務(wù)端的,有一個(gè)唯一標(biāo)識(shí)。在服務(wù)端保存Session的方法很多,內(nèi)存、數(shù)據(jù)庫(kù)、文件都有。集群的時(shí)候也要考慮Session的轉(zhuǎn)移,在大型的網(wǎng)站,一般會(huì)有專門的Session服務(wù)器集群,用來(lái)保存用戶會(huì)話,這個(gè)時(shí)候 Session 信息都是放在內(nèi)存的,使用一些緩存服務(wù)比如Memcached之類的來(lái)放 Session。
2. 思考一下服務(wù)端如何識(shí)別特定的客戶?這個(gè)時(shí)候Cookie就登場(chǎng)了。每次HTTP請(qǐng)求的時(shí)候,客戶端都會(huì)發(fā)送相應(yīng)的Cookie信息到服務(wù)端。實(shí)際上大多數(shù)的應(yīng)用都是用 Cookie 來(lái)實(shí)現(xiàn)Session跟蹤的,***次創(chuàng)建Session的時(shí)候,服務(wù)端會(huì)在HTTP協(xié)議中告訴客戶端,需要在 Cookie 里面記錄一個(gè)Session ID,以后每次請(qǐng)求把這個(gè)會(huì)話ID發(fā)送到服務(wù)器,我就知道你是誰(shuí)了。有人問(wèn),如果客戶端的瀏覽器禁用了 Cookie 怎么辦?一般這種情況下,會(huì)使用一種叫做URL重寫的技術(shù)來(lái)進(jìn)行會(huì)話跟蹤,即每次HTTP交互,URL后面都會(huì)被附加上一個(gè)諸如 sid=xxxxx 這樣的參數(shù),服務(wù)端據(jù)此來(lái)識(shí)別用戶。
3. Cookie其實(shí)還可以用在一些方便用戶的場(chǎng)景下,設(shè)想你某次登陸過(guò)一個(gè)網(wǎng)站,下次登錄的時(shí)候不想再次輸入賬號(hào)了,怎么辦?這個(gè)信息可以寫到Cookie里面,訪問(wèn)網(wǎng)站的時(shí)候,網(wǎng)站頁(yè)面的腳本可以讀取這個(gè)信息,就自動(dòng)幫你把用戶名給填了,能夠方便一下用戶。這也是Cookie名稱的由來(lái),給用戶的一點(diǎn)甜頭。
所以,總結(jié)一下:
Session是在服務(wù)端保存的一個(gè)數(shù)據(jù)結(jié)構(gòu),用來(lái)跟蹤用戶的狀態(tài),這個(gè)數(shù)據(jù)可以保存在集群、數(shù)據(jù)庫(kù)、文件中;
Cookie是客戶端保存用戶信息的一種機(jī)制,用來(lái)記錄用戶的一些信息,也是實(shí)現(xiàn)Session的一種方式。
1.狀態(tài)保持
· http協(xié)議是無(wú)狀態(tài)的:每次請(qǐng)求都是一次新的請(qǐng)求,不會(huì)記得之前通信的狀態(tài)
· 客戶端與服務(wù)器端的一次通信,就是一次會(huì)話
· 實(shí)現(xiàn)狀態(tài)保持的方式:在客戶端或服務(wù)器端存儲(chǔ)與會(huì)話有關(guān)的數(shù)據(jù)
· 存儲(chǔ)方式包括cookie、session,會(huì)話一般指session對(duì)象
· 使用cookie,所有數(shù)據(jù)存儲(chǔ)在客戶端,注意不要存儲(chǔ)敏感信息
· 推薦使用sesison方式,所有數(shù)據(jù)存儲(chǔ)在服務(wù)器端,在客戶端cookie中存儲(chǔ)session_id
· 狀態(tài)保持的目的是在一段時(shí)間內(nèi)跟蹤請(qǐng)求者的狀態(tài),可以實(shí)現(xiàn)跨頁(yè)面訪問(wèn)當(dāng)前請(qǐng)求者的數(shù)據(jù)
· 注意:不同的請(qǐng)求者之間不會(huì)共享這個(gè)數(shù)據(jù),與請(qǐng)求者一一對(duì)應(yīng)
2.啟用session(舉例Django)
· 使用django-admin startproject創(chuàng)建的項(xiàng)目默認(rèn)啟用
· 在settings.py文件中
項(xiàng)INSTALLED_APPS列表中添加:
'django.contrib.sessions',
項(xiàng)MIDDLEWARE_CLASSES列表中添加:
'django.contrib.sessions.middleware.SessionMiddleware',
· 禁用會(huì)話:刪除上面指定的兩個(gè)值,禁用會(huì)話將節(jié)省一些性能消耗
3.使用session
· 啟用會(huì)話后,每個(gè)HttpRequest對(duì)象將具有一個(gè)session屬性,它是一個(gè)類字典對(duì)象
· get(key, default=None):根據(jù)鍵獲取會(huì)話的值
· request.session.get(‘uname’,’’)
· clear():清除所有會(huì)話
· flush():刪除當(dāng)前的會(huì)話數(shù)據(jù)并刪除會(huì)話的Cookie
· del request.session['uname']:刪除會(huì)話
4.會(huì)話過(guò)期時(shí)間
· set_expiry(value):設(shè)置會(huì)話的超時(shí)時(shí)間
· 如果沒(méi)有指定,則兩個(gè)星期后過(guò)期
· 如果value是一個(gè)整數(shù),會(huì)話將在values秒沒(méi)有活動(dòng)后過(guò)期
· 若果value是一個(gè)timedelta對(duì)象,會(huì)話將在當(dāng)前時(shí)間加上這個(gè)指定的日期/時(shí)間過(guò)期
· 如果value為0,那么用戶會(huì)話的Cookie將在用戶的瀏覽器關(guān)閉時(shí)過(guò)期
· 如果value為None,那么會(huì)話永不過(guò)期




























