文章分享

開放、平等、協(xié)作、快速、分享

當(dāng)前位置:首頁>文章分享

HTTP Session、Cookie機(jī)制詳解

摘錄:HCTech 無錫和控電子   時(shí)間:2020-08-07   訪問量:3549

一、什么是http session,有什么用

HTTP協(xié)議本身是無狀態(tài)的,本身并不能支持服務(wù)端保存客戶端的狀態(tài)信息,于是,Web Server中引入了session的概念,用來保存客戶端的狀態(tài)信息。 

這 里用一個(gè)形象的比喻來解釋session的工作方式。假設(shè)Web Server是一個(gè)商場的存包處,HTTP Request是一個(gè)顧客,第一次來到存包處,管理員把顧客的物品存放在某一個(gè)柜子里面(這個(gè)柜子就相當(dāng)于Session),然后把一個(gè)號碼牌交給這個(gè)顧 客,作為取包憑證(這個(gè)號碼牌就是Session ID)。顧客(HTTP Request)下一次來的時(shí)候,就要把號碼牌(Session ID)交給存包處(Web Server)的管理員。管理員根據(jù)號碼牌(Session ID)找到相應(yīng)的柜子(Session),根據(jù)顧客(HTTP Request)的請求,Web Server可以取出、更換、添加柜子(Session)中的物品,Web Server也可以讓顧客(HTTP Request)的號碼牌和號碼牌對應(yīng)的柜子(Session)失效。顧客(HTTP Request)的忘性很大,管理員在顧客回去的時(shí)候(HTTP Response)都要重新提醒顧客記住自己的號碼牌(Session ID)。這樣,顧客(HTTP Request)下次來的時(shí)候,就又帶著號碼牌回來了。 
我們可以看到,Session ID實(shí)際上是在客戶端和服務(wù)端之間通過HTTP Request和HTTP Response傳來傳去的。

二、一般用來實(shí)現(xiàn)Session的方法有兩種·

1)URL重寫。 
Web Server在返回Response的時(shí)候,檢查頁面中所有的URL,包括所有的連接,和HTML Form的Action屬性,在這些URL后面加上“;jsessionid=XXX”。 
下一次,用戶訪問這個(gè)頁面中的URL。jsessionid就會傳回到Web Server。

2)Cookie。 

如果客戶端支持Cookie,Web Server在返回Response的時(shí)候,在Response的Header部分,加入一個(gè)“set-cookie: jsessionid=XXXX”header屬性,把jsessionid放在Cookie里傳到客戶端。 

客戶端會把Cookie存放在本地文件里,下一次訪問Web Server的時(shí)候,再把Cookie的信息放到HTTP Request的“Cookie”header屬性里面,這樣jsessionid就隨著HTTP Request返回給Web Server。

三、session的工作原理
1)當(dāng)一個(gè)用戶向服務(wù)器發(fā)送第一個(gè)請求時(shí),服務(wù)器為其建立一個(gè)session,并為此session創(chuàng)建一個(gè)標(biāo)識號;

2 ) 這個(gè)用戶隨后的所有請求都應(yīng)包括這個(gè)標(biāo)識號。服務(wù)器會校對這個(gè)標(biāo)識號以判斷請求屬于哪個(gè)session。

這種機(jī)制不使用IP作為標(biāo)識,是因?yàn)楹芏鄼C(jī)器是通過代理服務(wù)器方式上網(wǎng),沒法區(qū)分每一臺機(jī)器。

對于session標(biāo)識號(sessionID),有兩種方式實(shí)現(xiàn):cookies和URL重寫。

 

四、HttpSession總結(jié)
1、HTTP協(xié)議本身是“連接-請求-應(yīng)答-關(guān)閉連接”模式的,是一種無狀態(tài)協(xié)議(HTTP只是一個(gè)傳輸協(xié)議);
2、Cookie規(guī)范是為了給HTTP增加狀態(tài)跟蹤用的(如果要精確把握,建議仔細(xì)閱讀一下相關(guān)的RFC),但不是唯一的手段;
3、所謂Session,指的是客戶端和服務(wù)端之間的一段交互過程的狀態(tài)信息(數(shù)據(jù));這個(gè)狀態(tài)如何界定,生命期有多長,這是應(yīng)用本身的事情;
4、 由于B/S計(jì)算模型中計(jì)算是在服務(wù)器端完成的,客戶端只有簡單的顯示邏輯,所以,Session數(shù)據(jù)對客戶端應(yīng)該是透明的不可理解的并且應(yīng)該受控于服 務(wù)端;Session數(shù)據(jù)要么保存到服務(wù)端(HttpSession),要么在客戶端和服務(wù)端之間傳遞(Cookie或url rewritting或Hidden input);
5、由于HTTP本身的無狀態(tài)性,服務(wù)端無法知道客戶端相繼發(fā)來的請求是來自一個(gè)客戶的,所以,當(dāng)使用服務(wù)端HttpSession存儲會話數(shù)據(jù)的時(shí)候客戶端的每個(gè)請求都應(yīng)該包含一個(gè)session的標(biāo)識(sid, jsessionid 等等)來告訴服務(wù)端;
6、會話數(shù)據(jù)保存在服務(wù)端(如HttpSession)的好處是減少了HTTP請求的長度,提高了網(wǎng)絡(luò)傳輸效率;客戶端session信息存儲則相反;
7、 客戶端Session存儲只有一個(gè)辦法:cookie(url rewritting和hidden input因?yàn)闊o法做到持久化,不算,只能作為交換session id的方式,即a method of session tracking),而服務(wù)端做法大致也是一個(gè)道理:容器有個(gè)session管理器(如tomcat的 org.apache.catalina.session包里面的類),提供session的生命周期和持久化管理并提供訪問session數(shù)據(jù)的 api;
8、使用服務(wù)端還是客戶端session存儲要看應(yīng)用的實(shí)際情況的。一般來說不要求用戶注冊登錄的公共服務(wù)系統(tǒng)(如google)采用 cookie做客戶 端session存儲(如google的用戶偏好設(shè)置),而有用戶管理的系統(tǒng)則使用服務(wù)端存儲。原因很顯然:無需用戶登錄的系統(tǒng)唯一能夠標(biāo)識用戶的就是用 戶的電腦,換一臺機(jī)器就不知道誰是誰了,服務(wù)端session存儲根本不管用;而有用戶管理的系統(tǒng)則可以通過用戶id來管理用戶個(gè)人數(shù)據(jù),從而提供任意復(fù) 雜的個(gè)性化服務(wù);
9、客戶端和服務(wù)端的session存儲在性能、安全性、跨站能力、編程方便性等方面都有一定的區(qū)別,而且優(yōu)劣并非絕對(譬如 TheServerSide 號稱不使用HttpSession,所以性能好,這很顯然:一個(gè)具有上億的訪問用戶的系統(tǒng),要在服務(wù)端數(shù)據(jù)庫中檢索出用戶的偏好信息顯然是低效 的,Session管理器不管用什么數(shù)據(jù)結(jié)構(gòu)和算法都要耗費(fèi)大量內(nèi)存和CPU時(shí)間;而用cookie,則根本不用檢索和維護(hù)session數(shù)據(jù),服務(wù)器可 以做成無狀態(tài)的,當(dāng)然高效);
10、 所謂的“會話cookie”簡單的說就是沒有明確指明有效期的cookie,僅在瀏覽器當(dāng)前進(jìn)程生命期內(nèi)有效,可以被后繼的Set-Cookie操作清除掉。
當(dāng) 程序需要為某個(gè)客戶端的請求創(chuàng)建一個(gè)session的時(shí)候,服務(wù)器首先檢查這個(gè)客戶端的請求里是否已包含了一個(gè)session標(biāo)識 - 稱為 session id,如果已包含一個(gè)session id則說明以前已經(jīng)為此客戶端創(chuàng)建過session,服務(wù)器就按照session id把這個(gè) session檢索出來使用(如果檢索不到,可能會新建一個(gè)),如果客戶端請求不包含session id,則為此客戶端創(chuàng)建一個(gè)session并且生成一個(gè)與此session相關(guān)聯(lián)的session id,session id的值應(yīng)該是一個(gè)既不會重復(fù),又不容易被找到規(guī)律以仿造的字符串,這個(gè) session id將被在本次響應(yīng)中返回給客戶端保存。
保存這個(gè)session id的方式可以采用cookie,這樣在交互過程中瀏覽器可以自動的按照規(guī)則把這個(gè)標(biāo)識發(fā)揮給服務(wù)器。一般這個(gè)cookie的名字都是類似于SEEESIONID.
五、Session何時(shí)被創(chuàng)建、何時(shí)被刪除
何時(shí)創(chuàng)建:一 個(gè)常見的誤解是以為session在有客戶端訪問時(shí)就被創(chuàng)建,然而事實(shí)是直到某server端程序調(diào)用 HttpServletRequest.getSession(true)這樣的語句時(shí)才被創(chuàng)建,注意如果JSP沒有顯示的使用 <% @page session="false"%> 關(guān)閉session,則JSP文件在編譯成Servlet時(shí)將會自動加上這樣一條語句 HttpSession session = HttpServletRequest.getSession(true);這也是JSP中隱含的 session對象的來歷。由于session會消耗內(nèi)存資源,因此,如果不打算使用session,應(yīng)該在所有的JSP中關(guān)閉它。
何時(shí)刪除:
a.程序調(diào)用HttpSession.invalidate();
b.距離上一次收到客戶端發(fā)送的session id時(shí)間間隔超過了session的超時(shí)設(shè)置;
c.服務(wù)器進(jìn)程被停止(非持久session)
如何做到在瀏覽器關(guān)閉的時(shí)候刪除cookie?
嚴(yán)格的講,做不到這一點(diǎn)。可以做一點(diǎn)努力的辦法是在所有的客戶端頁面里使用javascript代碼window.oncolose來監(jiān)視瀏覽器的關(guān)閉動作,然后向服務(wù)器發(fā)送一個(gè)請求來刪除session。但是對于瀏覽器崩潰或者強(qiáng)行殺死進(jìn)程這些非常規(guī)手段仍然無能為力。
六、Session的其他問題
1、存放在session中的對象必須是可序列化的嗎?
不是必需的。要求對象可序列化只是為了session能夠在集群中被復(fù)制或者能夠持久保存或者在必要時(shí)server能夠暫時(shí)把session交換出內(nèi)存。
2、如何才能正確的應(yīng)付客戶端禁止cookie的可能性
對所有的URL使用URL重寫,包括超鏈接,form的action,和重定向的URL
3、開兩個(gè)瀏覽器窗口訪問應(yīng)用程序會使用同一個(gè)session還是不同的session
七、理解Cookie機(jī)制
1)cookie機(jī)制的基本原理就如上面的例子一樣簡單,但是還有幾個(gè)問題需要解決:“會員卡”如何分發(fā);“會員卡”的內(nèi)容;以及客戶如何使用“會員卡”。
2)正統(tǒng)的cookie分發(fā)是通過擴(kuò)展HTTP協(xié)議來實(shí)現(xiàn)的,服務(wù)器通過在HTTP的響應(yīng)頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應(yīng)的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。
3) 而cookie的使用是由瀏覽器按照一定的原則在后臺自動發(fā)送給服務(wù)器的。瀏覽器檢查所有存儲的cookie,如果某個(gè)cookie所聲明的作用范圍大于 等于將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發(fā)送給服務(wù)器。意思是麥當(dāng)勞的會員卡只能在麥當(dāng)勞的店里出示,如果某家 分店還發(fā)行了自己的會員卡,那么進(jìn)這家店的時(shí)候除了要出示麥當(dāng)勞的會員卡,還要出示這家店的會員卡。
八、cookie的內(nèi)容
主要包括:名字,值,過期時(shí)間,路徑和域。
路徑、域和作用范圍:其中域可以指定某一個(gè)域比如.google.com,相當(dāng)于總店招牌,比如寶潔公司,也可以指定一個(gè)域下的具體某臺機(jī)器比如www.google.com或者froogle.google.com,可以用飄柔來做比。
路徑就是跟在域名后面的URL路徑,比如/或者/foo等等,可以用某飄柔專柜做比。
路徑與域合在一起就構(gòu)成了cookie的作用范圍。
過期時(shí)間:如 果不設(shè)置過期時(shí)間,則表示這個(gè)cookie的生命期為瀏覽器會話期間,只要關(guān)閉瀏覽器窗口,cookie就消失了。這種生命期為瀏覽器會話期的 cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內(nèi)存里,當(dāng)然這種行為并不是規(guī)范規(guī)定的。如果設(shè)置了過期時(shí)間,瀏覽器 就會把cookie保存到硬盤上,關(guān)閉后再次打開瀏覽器,這些cookie仍然有效直到超過設(shè)定的過期時(shí)間。
瀏覽器差異:存 儲在硬盤上的cookie可以在不同的瀏覽器進(jìn)程間共享,比如兩個(gè)IE窗口。而對于保存在內(nèi)存里的cookie,不同的瀏覽器有不同的處理方式。對于 IE,在一個(gè)打開的窗口上按Ctrl-N(或者從文件菜單)打開的窗口可以與原窗口共享,而使用其他方式新開的IE進(jìn)程則不能共享已經(jīng)打開的窗口的內(nèi)存 cookie;對于Mozilla Firefox0.8,所有的進(jìn)程和標(biāo)簽頁都可以共享同樣的cookie。一般來說是用javascript的window.open打開的窗口會與原窗 口共享內(nèi)存cookie。瀏覽器對于會話cookie的這種只認(rèn)cookie不認(rèn)人的處理方式經(jīng)常給采用session機(jī)制的web應(yīng)用程序開發(fā)者造成很大的困擾。


上一篇:沒有了!

下一篇:windows下php-cgi進(jìn)程守護(hù),避免經(jīng)常出現(xiàn)php掛掉

在線咨詢

點(diǎn)擊這里給我發(fā)消息 售前咨詢專員

點(diǎn)擊這里給我發(fā)消息 售后服務(wù)專員

在線咨詢

免費(fèi)通話

24小時(shí)免費(fèi)咨詢

請輸入您的聯(lián)系電話,座機(jī)請加區(qū)號

免費(fèi)通話

微信掃一掃

微信聯(lián)系
返回頂部