Cookie機制
什么是Cookie
Cookie技術是客戶端的解決方案,Cookie就是由服務器發(fā)給客戶端的特殊信息顽分,而這些信息以文本文件的方式存放在客戶端货矮,然后客戶端每次向服務器發(fā)送請求的時候都會帶上這些特殊的信息补箍。
當用戶使用瀏覽器訪問一個支持Cookie的網(wǎng)站的時候,用戶會提供包括用戶名在內(nèi)的個人信息并且提交至服務器赦邻;接著髓棋,服務器在向客戶端回傳相應的超文本的同時也會發(fā)回這些個人信息,當然這些信息并不是存放在HTTP響應體(Response Body)中的惶洲,而是存放于HTTP響應頭(Response Header)按声;當客戶端瀏覽器接收到來自服務器的響應之后,瀏覽器會將這些信息存放在一個統(tǒng)一的位置湃鹊,對于Windows操作系統(tǒng)而言儒喊,我們可以從: [系統(tǒng)盤]:\Documents and Settings[用戶名]\Cookies目錄中找到存儲的Cookie;自此币呵,客戶端再向服務器發(fā)送請求的時候怀愧,都會把相應的Cookie再次發(fā)回至服務器侨颈。而這次,Cookie信息則存放在HTTP請求頭(Request Header)了芯义。有了Cookie這樣的技術實現(xiàn)哈垢,服務器在接收到來自客戶端瀏覽器的請求之后,就能夠通過分析存放于請求頭的Cookie得到客戶端特有的信息扛拨,從而動態(tài)生成與該客戶端相對應的內(nèi)容耘分。
Cookie就是這樣的一種機制。它可以彌補HTTP協(xié)議無狀態(tài)的不足绑警。在Session出現(xiàn)之前求泰,基本上所有的網(wǎng)站都采用Cookie來跟蹤會話。
有兩個http頭部是專門負責設置以及發(fā)送cookie的,它們分別是Set-Cookie以及Cookie计盒。當服務器返回給客戶端一個http響應信息時渴频,其中如果包含Set-Cookie這個頭部時,意思就是指示客戶端建立一個cookie北启,并且在后續(xù)的http請求中自動發(fā)送這個cookie到服務器端卜朗,直到這個cookie過期。
Java中把Cookie封裝成了javax.servlet.http.Cookie類咕村。Cookie對象使用key-value屬性對的形式保存用戶狀態(tài)场钉。通過request.getCookie()獲取客戶端提交的所有Cookie(以Cookie[]數(shù)組形式返回),通過response.addCookie(Cookiecookie)向客戶端設置Cookie懈涛。
Cookie的有效期
Cookie的maxAge決定著Cookie的有效期逛万,單位為秒(Second)。Cookie中通過getMaxAge()方法與setMaxAge(int maxAge)方法來讀寫maxAge屬性肩钠。
- maxAge屬性為正數(shù)
表示該Cookie會在maxAge秒之后自動失效泣港。瀏覽器會將maxAge為正數(shù)的Cookie持久化,即寫到對應的Cookie文件中价匠。無論客戶關閉了瀏覽器還是電腦,只要還在maxAge秒之前呛每,登錄網(wǎng)站時該Cookie仍然有效踩窖。
Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(Integer.MAX_VALUE); // 設置生命周期為MAX_VALUE,Cookie信息將永遠有效
response.addCookie(cookie); // 輸出到客戶端
- maxAge為負數(shù)
表示該Cookie僅在本瀏覽器窗口以及本窗口打開的子窗口內(nèi)有效,關閉窗口后該Cookie即失效晨横。maxAge為負數(shù)的Cookie洋腮,為臨時性Cookie,不會被持久化手形,不會被寫到Cookie文件中啥供。Cookie信息保存在瀏覽器內(nèi)存中,因此關閉瀏覽器該Cookie就消失了库糠。 - maxAge為0
表示刪除該Cookie
Cookie的修改和刪除
修改:新建一個同名的Cookie伙狐,添加到response中覆蓋原來的Cookie涮毫。
刪除:新建一個同名的Cookie,并將maxAge設置為0贷屎,并添加到response中覆蓋原來的Cookie
Cookie cookie = new Cookie("username","helloweenvsfei"); // 新建Cookie
cookie.setMaxAge(0); // 設置生命周期為0罢防,不能為負數(shù)
response.addCookie(cookie); // 必須執(zhí)行這一句
無論是刪除還是修改,新建的Cookie除value唉侄、maxAge之外的所有屬性咒吐,例如name、path属划、domain等恬叹,都要與原Cookie完全一樣,否則將不能實現(xiàn)對原Cookie的覆蓋
Cookie的domain屬性和path屬性
- domain
表示的是cookie所在的域同眯,默認為請求的地址绽昼,如網(wǎng)址為www.test.com/test/test.aspx,那么domain默認為www.test.com嗽测。而跨域訪問绪励,如域A為t1.test.com,域B為t2.test.com唠粥,那么在域A生產(chǎn)一個令域A和域B都能訪問的cookie就要將該cookie的domain設置為.test.com疏魏;如果要在域A生產(chǎn)一個令域A不能訪問而域B能訪問的cookie就要將該cookie的domain設置為t2.test.com。 - path
表示cookie所在的目錄晤愧,默認為/大莫,就是根目錄。在同一個服務器上有目錄如下:/test/,/test/cd/,/test/dd/官份,現(xiàn)設一個cookie1的path為/test/只厘,cookie2的path為/test/cd/,那么test下的所有頁面都可以訪問到cookie1舅巷,而/test/和/test/dd/的子頁面不能訪問cookie2羔味。這是因為cookie能讓其path路徑下的頁面訪問。
Session機制
除了使用Cookie钠右,Web應用程序中還經(jīng)常使用Session來記錄客戶端狀態(tài)赋元。Session是服務器端使用的一種記錄客戶端狀態(tài)的機制,使用上比Cookie簡單一些飒房,相應的也增加了服務器的存儲壓力搁凸。
什么是Session
Session是另一種記錄客戶狀態(tài)的機制,不同的是Cookie保存在客戶端瀏覽器中狠毯,而Session保存在服務器上护糖。
Java中通過調(diào)用HttpServletRequest的getSession方法(使用true作為參數(shù))創(chuàng)建的。在創(chuàng)建了Session的同時嚼松,服務器會為該Session生成唯一的Session id嫡良,而這個Session id在隨后的請求中會被用來重新獲得已經(jīng)創(chuàng)建的Session锰扶;在Session被創(chuàng)建之后,就可以調(diào)用Session相關的方法往Session中增加內(nèi)容了皆刺,而這些內(nèi)容只會保存在服務器中少辣,發(fā)到客戶端的只有Session id;當客戶端再次發(fā)送請求的時候羡蛾,會將這個Session id帶上漓帅,服務器接受到請求之后就會依據(jù)Session id找到相應的Session,從而再次使用之痴怨。正式這樣一個過程忙干,用戶的狀態(tài)也就得以保持了。
Session的有效期
由于會有越來越多的用戶訪問服務器浪藻,因此Session也會越來越多捐迫。為防止內(nèi)存溢出,服務器會把長時間內(nèi)沒有活躍的Session從內(nèi)存刪除爱葵。這個時間就是Session的超時時間施戴。如果超過了超時時間沒訪問過服務器,Session就自動失效了萌丈。
Session的超時時間為maxInactiveInterval屬性赞哗,可以通過對應的getMaxInactiveInterval()獲取,通過setMaxInactiveInterval(longinterval)修改辆雾。
Session的超時時間也可以在web.xml中修改肪笋。另外,通過調(diào)用Session的invalidate()方法可以使Session失效度迂。
Session對瀏覽器的要求
雖然Session保存在服務器藤乙,對客戶端是透明的,它的正常運行仍然需要客戶端瀏覽器的支持惭墓。這是因為Session需要使用Cookie作為識別標志坛梁。HTTP協(xié)議是無狀態(tài)的,Session不能依據(jù)HTTP連接來判斷是否為同一客戶腊凶,因此服務器向客戶端瀏覽器發(fā)送一個名為JSESSIONID的Cookie罚勾,它的值為該Session的id(也就是HttpSession.getId()的返回值)。Session依據(jù)該Cookie來識別是否為同一用戶吭狡。
注意:新開的瀏覽器窗口會生成新的Session,但子窗口除外丈莺。子窗口會共用父窗口的Session划煮。例如漾峡,在鏈接上右擊边琉,在彈出的快捷菜單中選擇“在新窗口中打開”時仆抵,子窗口便可以訪問父窗口的Session。
URL地址重寫
URL地址重寫是對客戶端不支持Cookie的解決方案刺彩。URL地址重寫的原理是將該用戶Session的id信息重寫到URL地址中。服務器能夠解析重寫后的URL獲取Session的id缎岗。這樣即使客戶端不支持Cookie哈打,也可以使用Session來記錄用戶狀態(tài)。HttpServletResponse類提供了encodeURL(Stringurl)實現(xiàn)URL地址重寫挖炬,例如:
<td>
<a href="<%=response.encodeURL("index.jsp?c=1&wd=Java") %>">
Homepage</a>
</td>
該方法會自動判斷客戶端是否支持Cookie揽浙。如果客戶端支持Cookie,會將URL原封不動地輸出來意敛。如果客戶端不支持Cookie馅巷,則會將用戶Session的id重寫到URL中。重寫后的輸出可能是這樣的:
<td>
<a href="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=1&wd=Java">Homepage</a>
</td>
Cookie與Session的區(qū)別
- Cookie數(shù)據(jù)存放在客戶的瀏覽器上草姻,Session數(shù)據(jù)放在服務器上钓猬;
- Cookie不是很安全,別人可以分析存放在本地的Cookie并進行Cookie欺騙撩独,考慮到安全應當使用Session敞曹;
- Session會在一定時間內(nèi)保存在服務器上。當訪問增多综膀,會比較占用你服務器的性能澳迫。考慮到減輕服務器性能方面僧须,應當使用Cookie纲刀;
- 單個Cookie在客戶端的限制是3K,就是說一個站點在客戶端存放的Cookie不能超過3K担平;