1、為什么要有cookie
看個(gè)實(shí)際生活的例子:
學(xué)校門口有家飯店味道不錯(cuò),小明去吃了一次,確實(shí)味道不錯(cuò),這周小明又去這家飯店吃飯,結(jié)賬時(shí),小明說:”我上周來過,這是第二次了,能不能打個(gè)折?“。老板說:”你來過?我不記得啊(無狀態(tài))“。小明表示很生氣,明明來過老板竟然不記得。老板想了個(gè)法子,給小明發(fā)了張卡片(cookie),上面寫著小明的信息,下次小明拿著卡片來老板就認(rèn)識(shí)了。
回到正題,cookie用在http請求中,而http是無狀態(tài)協(xié)議,它的每個(gè)請求都是完全獨(dú)立的,服務(wù)端無法判別用戶狀態(tài),cookie用來告訴服務(wù)端用戶的狀態(tài)信息。客戶端用戶第一次發(fā)送請求給服務(wù)端時(shí),服務(wù)端在返回的響應(yīng)中發(fā)給用戶一個(gè)cookie,里面記錄了用戶的信息,下次用戶再發(fā)送http請求給服務(wù)端時(shí),會(huì)攜帶上cookie,服務(wù)端檢查cookie獲取用戶的狀態(tài)信息。
2、cookie的內(nèi)容
cookie的內(nèi)容主要是服務(wù)端寫入的,由客戶端存儲(chǔ)在本地,cookie其實(shí)是以字符串的形式存儲(chǔ)的。打開谷歌開發(fā)者工具的Application中的Cookie,可以看到cookie具有以下字段
Name Value
cookie以鍵值對的形式存儲(chǔ)用戶數(shù)據(jù)
Domain Path
不同域名是無法操作彼此cookie的,而且必須滿足path一樣或者是其子路徑才能相互訪問彼此的cookie。
domain用來設(shè)置可以使用cookie的域名,如果想讓一級域名下的兩個(gè)二級域名都能使用cookie,例如imag.baidu.com和www.baidu.com,可以設(shè)置domain為baidu.com,但不能設(shè)置為.com,這樣兩個(gè)二級域名都能使用。path屬性設(shè)置允許使用cookie的路徑,例如設(shè)置為根路徑"/",表示允許根路徑以及根路徑下的所有子路徑都可以使用cookie
所以domain和path共同決定了cookie能否被瀏覽器自動(dòng)添加到請求頭部中發(fā)送出去。如果沒有設(shè)置這兩個(gè)選項(xiàng),則會(huì)使用默認(rèn)值。domain的默認(rèn)值為設(shè)置該cookie的網(wǎng)頁所在的域名,path默認(rèn)值為設(shè)置該cookie的網(wǎng)頁所在的目錄。
此外,如果是跨域請求,例如XMLHttpRequest請求,默認(rèn)是不會(huì)自動(dòng)攜帶cookie的。
Expires/Max-Age
cookie的過期時(shí)間,Expires是具體日期,Max-Age是一段時(shí)間
size
cookie的大小,一般是4k,此外cookie的個(gè)數(shù)也有限制,不同瀏覽器cookie的個(gè)數(shù)限制不同
HttpOnly
該cookie數(shù)據(jù)是否只用來在http請求中傳遞,默認(rèn)為false,如果設(shè)置該字段為true,客戶端無法用js訪問或者操作該cookie,這條cookie信息不會(huì)出現(xiàn)在document.cookie的字符串中。
Secure
默認(rèn)為false,設(shè)置該字段為true則該cookie不會(huì)攜帶在http協(xié)議的請求中,只能攜帶在安全的https協(xié)議請求中
3、cookie的使用
當(dāng)網(wǎng)頁要發(fā)http請求時(shí),瀏覽器會(huì)先檢查是否有相應(yīng)的cookie,有則自動(dòng)添加在request header中的cookie字段中。這些是瀏覽器自動(dòng)幫我們做的,而且每一次http請求瀏覽器都會(huì)自動(dòng)幫我們做。這個(gè)特點(diǎn)很重要,因?yàn)檫@關(guān)系到“什么樣的數(shù)據(jù)適合存儲(chǔ)在cookie中”。
因?yàn)槊看螢g覽器發(fā)送http請求都會(huì)自動(dòng)攜帶cookie,會(huì)增加網(wǎng)絡(luò)開銷,所以最好只存放每次請求都需要發(fā)送給服務(wù)端的數(shù)據(jù),比如身份認(rèn)證信息。
客戶端使用js設(shè)置 cookie,客戶端可以設(shè)置cookie 的下列選項(xiàng):expires、domain、path、secure(有條件:只有在https協(xié)議的網(wǎng)頁中,客戶端設(shè)置secure類型的 cookie 才能成功),但無法設(shè)置HttpOnly選項(xiàng)。document.cookie可以獲取cookie字符串,也可以設(shè)置cookie。
document.cookie="age=12; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/";
值得注意的是,瀏覽器提交Cookie時(shí)只會(huì)提交name和value屬性,maxAge屬性只被瀏覽器用來判斷Cookie是否過期。
當(dāng)要設(shè)置多個(gè)cookie時(shí),必須重復(fù)設(shè)置document.cookie = "key=name"。
要想修改一個(gè)cookie,只需要重新賦值就行,舊的值會(huì)被新的值覆蓋。但要注意一點(diǎn),在設(shè)置新cookie時(shí),path/domain這幾個(gè)選項(xiàng)一定要舊cookie 保持一樣。否則不會(huì)修改舊值,而是添加了一個(gè)新的 cookie。刪除一個(gè)cookie?也挺簡單,也是重新賦值,只要將這個(gè)新cookie的expires?選項(xiàng)設(shè)置為一個(gè)過去的時(shí)間點(diǎn)就行了。但要注意,path/domain/這幾個(gè)選項(xiàng)一定要舊cookie 保持一致。
服務(wù)端的response header中有一項(xiàng)叫set-cookie,是服務(wù)端專門用來設(shè)置cookie的。