1. 前言
朋友問我cookie是什么聚至,用來干什么的,可是我居然無法清楚明白簡短地向其闡述cookie雀哨,這不禁讓我陷入了沉思:為什么我無法解釋清楚固额,我對學(xué)習(xí)的方法產(chǎn)生了懷疑眠蚂!在知乎上看到有人推薦使用費爾曼學(xué)習(xí)技巧,于是在重新學(xué)習(xí)cookie的過程中使用了該技巧來試驗斗躏,效果有待驗證逝慧!
在學(xué)習(xí)一個新的知識點前,我們應(yīng)該明白自己的學(xué)習(xí)目標(biāo)瑟捣,要帶著疑問去學(xué)習(xí)馋艺,該小節(jié)須要了解:
- 什么是cookie,cookie的作用
- cookie的工作機(jī)制迈套,即cookie是運作流程
- cookie的基本屬性(4個)以及我們?nèi)绾问褂胏ookie
2. 什么是cookie
HTTP協(xié)議本身是無狀態(tài)的捐祠。什么是無狀態(tài)呢,即服務(wù)器無法判斷用戶身份桑李。Cookie實際上是一小段的文本信息(key-value格式)踱蛀。客戶端向服務(wù)器發(fā)起請求贵白,如果服務(wù)器需要記錄該用戶狀態(tài)率拒,就使用response向客戶端瀏覽器頒發(fā)一個Cookie〗模客戶端瀏覽器會把Cookie保存起來猬膨。當(dāng)瀏覽器再請求該網(wǎng)站時,瀏覽器把請求的網(wǎng)址連同該Cookie一同提交給服務(wù)器呛伴。服務(wù)器檢查該Cookie勃痴,以此來辨認(rèn)用戶狀態(tài)谒所。
打個比方,我們?nèi)ャy行辦理儲蓄業(yè)務(wù)沛申,第一次給你辦了張銀行卡劣领,里面存放了身份證、密碼铁材、手機(jī)等個人信息尖淘。當(dāng)你下次再來這個銀行時,銀行機(jī)器能識別你的卡著觉,從而能夠直接辦理業(yè)務(wù)村生。
3. cookie機(jī)制
當(dāng)用戶第一次訪問并登陸一個網(wǎng)站的時候,cookie的設(shè)置以及發(fā)送會經(jīng)歷以下4個步驟:
客戶端發(fā)送一個請求到服務(wù)器 --》 服務(wù)器發(fā)送一個HttpResponse響應(yīng)到客戶端固惯,其中包含Set-Cookie的頭部 --》 客戶端保存cookie梆造,之后向服務(wù)器發(fā)送請求時缴守,HttpRequest請求中會包含一個Cookie的頭部 --》服務(wù)器返回響應(yīng)數(shù)據(jù)
為了探究這個過程葬毫,寫了代碼進(jìn)行測試,如下:
我在doGet方法中屡穗,new了一個Cookie對象并將其加入到了HttpResponse對象中
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
// 設(shè)置生命周期為MAX_VALUE
cookie.setMaxAge(Integer.MAX_VALUE);
resp.addCookie(cookie);
}
瀏覽器輸入地址進(jìn)行訪問贴捡,結(jié)果如圖所示:
可見Response Headers中包含Set-Cookie頭部,而Request Headers中包含了Cookie頭部村砂。name和value正是上述設(shè)置的烂斋。
4. cookie屬性項
屬性項 | 屬性項介紹 |
---|---|
NAME=VALUE | 鍵值對,可以設(shè)置要保存的 Key/Value础废,注意這里的 NAME 不能和其他屬性項的名字一樣 |
Expires | 過期時間汛骂,在設(shè)置的某個時間點后該 Cookie 就會失效 |
Domain | 生成該 Cookie 的域名,如 domain="www.baidu.com" |
Path | 該 Cookie 是在當(dāng)前的哪個路徑下生成的评腺,如 path=/wp-admin/ |
Secure | 如果設(shè)置了這個屬性帘瞭,那么只會在 SSH 連接時才會回傳該 Cookie |
Expires
該屬性用來設(shè)置Cookie的有效期。Cookie中的maxAge用來表示該屬性蒿讥,單位為秒蝶念。Cookie中通過getMaxAge()和setMaxAge(int maxAge)來讀寫該屬性。maxAge有3種值芋绸,分別為正數(shù)媒殉,負(fù)數(shù)和0。
如果maxAge屬性為正數(shù)摔敛,則表示該Cookie會在maxAge秒之后自動失效廷蓉。瀏覽器會將maxAge為正數(shù)的Cookie持久化,即寫到對應(yīng)的Cookie文件中(每個瀏覽器存儲的位置不一致)马昙。無論客戶關(guān)閉了瀏覽器還是電腦桃犬,只要還在maxAge秒之前售貌,登錄網(wǎng)站時該Cookie仍然有效。下面代碼中的Cookie信息將永遠(yuǎn)有效疫萤。
Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
// 設(shè)置生命周期為MAX_VALUE颂跨,永久有效
cookie.setMaxAge(Integer.MAX_VALUE);
resp.addCookie(cookie);
當(dāng)maxAge屬性為負(fù)數(shù),則表示該Cookie只是一個臨時Cookie扯饶,不會被持久化恒削,僅在本瀏覽器窗口或者本窗口打開的子窗口中有效,關(guān)閉瀏覽器后該Cookie立即失效尾序。
Cookie cookie = new Cookie("mcrwayfun",System.currentTimeMillis()+"");
// MaxAge為負(fù)數(shù)钓丰,是一個臨時Cookie,不會持久化
cookie.setMaxAge(-1);
resp.addCookie(cookie);
可以看到每币,當(dāng)MaxAge為-1時携丁,時間已經(jīng)過期
當(dāng)maxAge為0時,表示立即刪除Cookie
Cookie[] cookies = req.getCookies();
Cookie cookie = null;
// get Cookie
for (Cookie ck : cookies) {
if ("mcrwayfun".equals(ck.getName())) {
cookie = ck;
break;
}
}
if (null != cookie) {
// 刪除一個cookie
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
那么maxAge設(shè)置為負(fù)值和0到底有什么區(qū)別呢兰怠?
maxAge設(shè)置為0表示立即刪除該Cookie梦鉴,如果在debug的模式下,執(zhí)行上述方法揭保,可以看見cookie立即被刪除了肥橙。
maxAge設(shè)置為負(fù)數(shù),能看到Expires屬性改變了秸侣,但Cookie仍然會存在一段時間直到關(guān)閉瀏覽器或者重新打開瀏覽器存筏。
修改或者刪除Cookie
HttpServletResponse提供的Cookie操作只有一個addCookie(Cookie cookie),所以想要修改Cookie只能使用一個同名的Cookie來覆蓋原先的Cookie味榛。如果要刪除某個Cookie椭坚,則只需要新建一個同名的Cookie,并將maxAge設(shè)置為0搏色,并覆蓋原來的Cookie即可善茎。
新建的Cookie,除了value继榆、maxAge之外的屬性巾表,比如name、path略吨、domain都必須與原來的一致才能達(dá)到修改或者刪除的效果集币。否則,瀏覽器將視為兩個不同的Cookie不予覆蓋翠忠。
值得注意的是鞠苟,從客戶端讀取Cookie時,包括maxAge在內(nèi)的其他屬性都是不可讀的,也不會被提交当娱。瀏覽器提交Cookie時只會提交name和value屬性吃既,maxAge屬性只被瀏覽器用來判斷Cookie是否過期,而不能用服務(wù)端來判斷跨细。
我們無法在服務(wù)端通過cookie.getMaxAge()來判斷該cookie是否過期鹦倚,maxAge只是一個只讀屬性,值永遠(yuǎn)為-1冀惭。當(dāng)cookie過期時震叙,瀏覽器在與后臺交互時會自動篩選過期cookie,過期了的cookie就不會被攜帶了散休。
Cookie的域名
Cookie是不可以跨域名的媒楼,隱私安全機(jī)制禁止網(wǎng)站非法獲取其他網(wǎng)站的Cookie。
正常情況下戚丸,同一個一級域名下的兩個二級域名也不能交互使用Cookie划址,比如test1.mcrwayfun.com和test2.mcrwayfun.com,因為二者的域名不完全相同限府。如果想要mcrwayfun.com名下的二級域名都可以使用該Cookie夺颤,需要設(shè)置Cookie的domain參數(shù)為.mcrwayfun.com,這樣使用test1.mcrwayfun.com和test2.mcrwayfun.com就能訪問同一個cookie
一級域名又稱為頂級域名谣殊,一般由字符串+后綴組成拂共。熟悉的一級域名有baidu.com,qq.com姻几。com,cn势告,net等均是常見的后綴蛇捌。
二級域名是在一級域名下衍生的,比如有個一級域名為mcrfun.com咱台,則blog.mcrfun.com和www.mcrfun.com均是其衍生出來的二級域名络拌。
Cookie的路徑
path屬性決定允許訪問Cookie的路徑。比如回溺,設(shè)置為"/"表示允許所有路徑都可以使用Cookie