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