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