簡(jiǎn)介
由于HTTP協(xié)議是無(wú)狀態(tài)的協(xié)議,所以服務(wù)端需要記錄用戶的狀態(tài)時(shí),就需要用某種機(jī)制來(lái)識(shí)具體的用戶烟勋,這個(gè)機(jī)制就是Session會(huì)話(Session)跟蹤是Web程序中常用的技術(shù)启摄,用來(lái)跟蹤用戶的整個(gè)會(huì)話。常用的會(huì)話跟蹤技術(shù)是Cookie與Session实束。Cookie通過(guò)在客戶端記錄信息確定用戶身份奥秆,Session通過(guò)在服務(wù)器端記錄信息確定用戶身份。
在程序中咸灿,會(huì)話跟蹤是很重要的事情构订。理論上,一個(gè)用戶的所有請(qǐng)求操作都應(yīng)該屬于同一個(gè)會(huì)話析显,而另一個(gè)用戶的所有請(qǐng)求操作則應(yīng)該屬于另一個(gè)會(huì)話鲫咽,二者不能混淆。例如谷异,用戶A在超市購(gòu)買的任何商品都應(yīng)該放在A的購(gòu)物車內(nèi)分尸,不論是用戶A什么時(shí)間購(gòu)買的,這都是屬于同一個(gè)會(huì)話的歹嘹,不能放入用戶B或用戶C的購(gòu)物車內(nèi)箩绍,這不屬于同一個(gè)會(huì)話。
而Web應(yīng)用程序是使用HTTP協(xié)議傳輸數(shù)據(jù)的尺上。HTTP協(xié)議是無(wú)狀態(tài)的協(xié)議材蛛。一旦數(shù)據(jù)交換完畢,客戶端與服務(wù)器端的連接就會(huì)關(guān)閉怎抛,再次交換數(shù)據(jù)需要建立新的連接卑吭。這就意味著服務(wù)器無(wú)法從連接上跟蹤會(huì)話。即用戶A購(gòu)買了一件商品放入購(gòu)物車內(nèi)马绝,當(dāng)再次購(gòu)買商品時(shí)服務(wù)器已經(jīng)無(wú)法判斷該購(gòu)買行為是屬于用戶A的會(huì)話還是用戶B的會(huì)話了豆赏。要跟蹤該會(huì)話,必須引入一種機(jī)制。
cookie
Cookie實(shí)際上是一小段的文本信息掷邦“渍停客戶端請(qǐng)求服務(wù)器,如果服務(wù)器需要記錄該用戶狀態(tài)抚岗,就使用response向客戶端瀏覽器頒發(fā)一個(gè)Cookie或杠。客戶端瀏覽器會(huì)把Cookie保存起來(lái)宣蔚。當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí)向抢,瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器。服務(wù)器檢查該Cookie件已,以此來(lái)辨認(rèn)用戶狀態(tài)笋额。服務(wù)器還可以根據(jù)需要修改Cookie的內(nèi)容。
cookie機(jī)制
cookie機(jī)制采用的是在客戶端保持狀態(tài)的方案篷扩。它是在用戶端的會(huì)話狀態(tài)的存貯機(jī)制兄猩,他需要用戶打開客戶端的cookie支持。cookie的作用就是為了解決HTTP協(xié)議無(wú)狀態(tài)的缺陷所作的努力鉴未,cookie機(jī)制本質(zhì)上是http協(xié)議的一個(gè)擴(kuò)展枢冤。
有兩個(gè)http頭部是專門負(fù)責(zé)設(shè)置以及發(fā)送cookie的,它們分別是Set-Cookie以及Cookie。當(dāng)服務(wù)器返回給客戶端一個(gè)http響應(yīng)信息時(shí)铜秆,其中如果包含Set-Cookie這個(gè)頭部時(shí)淹真,意思就是提示瀏覽器按照指示生成相應(yīng)的cookie。并且在后續(xù)的http請(qǐng)求中自動(dòng)發(fā)送這個(gè)cookie到服務(wù)器端连茧,直到這個(gè)cookie過(guò)期核蘸。
然而純粹的客戶端腳本如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
客戶端瀏覽器訪問(wèn)服務(wù)器的時(shí)候讨衣,服務(wù)器把客戶端信息以某種形式記錄在服務(wù)器上。這就是Session式镐》凑颍客戶端瀏覽器再次訪問(wèn)時(shí)只需要從該Session中查找該客戶的狀態(tài)就可以了。session 是一個(gè)抽象概念娘汞,抽象為“會(huì)話”歹茶,進(jìn)而衍生出“會(huì)話狀態(tài)”
session機(jī)制
session機(jī)制是一種服務(wù)器端的機(jī)制,服務(wù)器使用一種類似于散列表的結(jié)構(gòu)(也可能就是使用散列表)來(lái)保存信息你弦,session機(jī)制就是通過(guò)檢查服務(wù)器上的“客戶明細(xì)表”來(lái)確認(rèn)客戶身份惊豺。session相當(dāng)于程序在服務(wù)器上建立的一份客戶檔案,客戶來(lái)訪的時(shí)候只需要查詢客戶檔案表就可以了
當(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朽褪。Session依據(jù)該Cookie中的session id來(lái)識(shí)別是否為同一用戶置吓。維持一個(gè)會(huì)話的核心就是客戶端的唯一標(biāo)識(shí),即 session id
但cookie可以被人為的禁止缔赠,則必須有其他機(jī)制以便在cookie被禁止時(shí)仍然能夠把session id傳遞回服務(wù)器衍锚。經(jīng)常被使用的一種技術(shù)叫做URL重寫,就是把session id直接附加在URL路徑的后面嗤堰。還有一種技術(shù)叫做表單隱藏字段戴质。就是服務(wù)器會(huì)自動(dòng)修改表單,添加一個(gè)隱藏字段,在被傳遞回客戶端之前告匠,在 form 里面加入一個(gè)hidden域戈抄,設(shè)置JSeesionId,以便在表單提交時(shí)能夠把session id傳遞回服務(wù)器
cookie和session的特性
存取方式的不同
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容器類。
隱私策略的不同
Cookie存儲(chǔ)在客戶端閱讀器中荸实,對(duì)客戶端是可見(jiàn)的匀们,客戶端的一些程序可能會(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ù)畴蒲。
有效期上的不同
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)存溢出纠吴。
服務(wù)器壓力的不同
Cookie保管在客戶端硬鞍,不占用服務(wù)器資源。假如并發(fā)閱讀的用戶十分多戴已,Cookie是很好的選擇
Session是保管在服務(wù)器端的,每個(gè)用戶都會(huì)產(chǎn)生一個(gè)Session锅减。假如并發(fā)訪問(wèn)的用戶十分多糖儡,會(huì)產(chǎn)生十分多的Session,耗費(fèi)大量的內(nèi)存
瀏覽器支持的不同
Cookie是需要客戶端瀏覽器支持的怔匣。假如客戶端禁用了Cookie握联,或者不支持Cookie,則會(huì)話跟蹤會(huì)失效每瞒。
假如客戶端瀏覽器不支持Cookie金闽,需要運(yùn)用Session,使用URL地址重寫剿骨。需要注意的是一切的用到Session程序的URL都要進(jìn)行URL地址重寫代芜,否則Session會(huì)話跟蹤還會(huì)失效。
假如客戶端支持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相干)
跨域支持上的不同
Cookie支持跨域名訪問(wèn)苹威,例如將domain屬性設(shè)置為“.biaodianfu.com”昆咽,則以“.biaodianfu.com”為后綴的一切域名均能夠訪問(wèn)該Cookie
而Session則不會(huì)支持跨域名訪問(wèn)。Session僅在他所在的域名內(nèi)有效