1、為什么要有cookie
看個(gè)實(shí)際生活的例子:
學(xué)校門(mén)口有家飯店味道不錯(cuò)骂因,小明去吃了一次,確實(shí)味道不錯(cuò)赃泡,這周小明又去這家飯店吃飯寒波,結(jié)賬時(shí),小明說(shuō):”我上周來(lái)過(guò)升熊,這是第二次了俄烁,能不能打個(gè)折?“级野。老板說(shuō):”你來(lái)過(guò)页屠?我不記得啊(無(wú)狀態(tài))“勺阐。小明表示很生氣卷中,明明來(lái)過(guò)老板竟然不記得。老板想了個(gè)法子渊抽,給小明發(fā)了張卡片(cookie)蟆豫,上面寫(xiě)著小明的信息,下次小明拿著卡片來(lái)老板就認(rèn)識(shí)了懒闷。
回到正題十减,cookie用在http請(qǐng)求中栈幸,而http是無(wú)狀態(tài)協(xié)議,它的每個(gè)請(qǐng)求都是完全獨(dú)立的帮辟,服務(wù)端無(wú)法判別用戶(hù)狀態(tài)速址,cookie用來(lái)告訴服務(wù)端用戶(hù)的狀態(tài)信息∮删裕客戶(hù)端用戶(hù)第一次發(fā)送請(qǐng)求給服務(wù)端時(shí)芍锚,服務(wù)端在返回的響應(yīng)中發(fā)給用戶(hù)一個(gè)cookie,里面記錄了用戶(hù)的信息蔓榄,下次用戶(hù)再發(fā)送http請(qǐng)求給服務(wù)端時(shí)并炮,會(huì)攜帶上cookie,服務(wù)端檢查cookie獲取用戶(hù)的狀態(tài)信息甥郑。
2逃魄、cookie的內(nèi)容
cookie的內(nèi)容主要是服務(wù)端寫(xiě)入的,由客戶(hù)端存儲(chǔ)在本地澜搅,cookie其實(shí)是以字符串的形式存儲(chǔ)的伍俘。打開(kāi)谷歌開(kāi)發(fā)者工具的Application中的Cookie,可以看到cookie具有以下字段
Name Value
cookie以鍵值對(duì)的形式存儲(chǔ)用戶(hù)數(shù)據(jù)
Domain Path
不同域名是無(wú)法操作彼此cookie的勉躺,而且必須滿(mǎn)足path一樣或者是其子路徑才能相互訪問(wèn)彼此的cookie癌瘾。
domain用來(lái)設(shè)置可以使用cookie的域名,如果想讓一級(jí)域名下的兩個(gè)二級(jí)域名都能使用cookie赂蕴,例如imag.baidu.com和www.baidu.com柳弄,可以設(shè)置domain為baidu.com,但不能設(shè)置為.com概说,這樣兩個(gè)二級(jí)域名都能使用碧注。path屬性設(shè)置允許使用cookie的路徑,例如設(shè)置為根路徑"/"糖赔,表示允許根路徑以及根路徑下的所有子路徑都可以使用cookie
所以domain和path共同決定了cookie能否被瀏覽器自動(dòng)添加到請(qǐng)求頭部中發(fā)送出去萍丐。如果沒(méi)有設(shè)置這兩個(gè)選項(xiàng),則會(huì)使用默認(rèn)值放典。domain的默認(rèn)值為設(shè)置該cookie的網(wǎng)頁(yè)所在的域名逝变,path默認(rèn)值為設(shè)置該cookie的網(wǎng)頁(yè)所在的目錄。
此外奋构,如果是跨域請(qǐng)求壳影,例如XMLHttpRequest請(qǐng)求,默認(rèn)是不會(huì)自動(dòng)攜帶cookie的弥臼。
Expires/Max-Age
cookie的過(guò)期時(shí)間宴咧,Expires是具體日期,Max-Age是一段時(shí)間
size
cookie的大小径缅,一般是4k掺栅,此外cookie的個(gè)數(shù)也有限制烙肺,不同瀏覽器cookie的個(gè)數(shù)限制不同
HttpOnly
該cookie數(shù)據(jù)是否只用來(lái)在http請(qǐng)求中傳遞,默認(rèn)為false氧卧,如果設(shè)置該字段為true桃笙,客戶(hù)端無(wú)法用js訪問(wèn)或者操作該cookie,這條cookie信息不會(huì)出現(xiàn)在document.cookie的字符串中沙绝。
Secure
默認(rèn)為false搏明,設(shè)置該字段為true則該cookie不會(huì)攜帶在http協(xié)議的請(qǐng)求中,只能攜帶在安全的https協(xié)議請(qǐng)求中
3闪檬、cookie的使用
當(dāng)網(wǎng)頁(yè)要發(fā)http請(qǐng)求時(shí)熏瞄,瀏覽器會(huì)先檢查是否有相應(yīng)的cookie,有則自動(dòng)添加在request header中的cookie字段中谬以。這些是瀏覽器自動(dòng)幫我們做的,而且每一次http請(qǐng)求瀏覽器都會(huì)自動(dòng)幫我們做由桌。這個(gè)特點(diǎn)很重要为黎,因?yàn)檫@關(guān)系到“什么樣的數(shù)據(jù)適合存儲(chǔ)在cookie中”。
因?yàn)槊看螢g覽器發(fā)送http請(qǐng)求都會(huì)自動(dòng)攜帶cookie行您,會(huì)增加網(wǎng)絡(luò)開(kāi)銷(xiāo)铭乾,所以最好只存放每次請(qǐng)求都需要發(fā)送給服務(wù)端的數(shù)據(jù),比如身份認(rèn)證信息娃循。
客戶(hù)端使用js設(shè)置 cookie炕檩,客戶(hù)端可以設(shè)置cookie 的下列選項(xiàng):expires、domain捌斧、path笛质、secure(有條件:只有在https協(xié)議的網(wǎng)頁(yè)中,客戶(hù)端設(shè)置secure類(lèi)型的 cookie 才能成功)捞蚂,但無(wú)法設(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屬性只被瀏覽器用來(lái)判斷Cookie是否過(guò)期丁存。
當(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?也挺簡(jiǎn)單晕窑,也是重新賦值,只要將這個(gè)新cookie的expires?選項(xiàng)設(shè)置為一個(gè)過(guò)去的時(shí)間點(diǎn)就行了卵佛。但要注意杨赤,path/domain/這幾個(gè)選項(xiàng)一定要舊cookie 保持一致。
服務(wù)端的response header中有一項(xiàng)叫set-cookie截汪,是服務(wù)端專(zhuān)門(mén)用來(lái)設(shè)置cookie的疾牲。