由於HTTP協議是無狀態的,每次請求都是獨立的,服務器端沒法判斷兩次請求是否來自同一個用戶,進而也就沒法判斷用戶的登陸狀態,也不知道用戶上一次作了什麼。因此Cookie就是用來繞開HTTP的無狀態性的「額外手段」之一。服務器能夠設置或讀取Cookies中包含信息,藉此維護用戶跟服務器會話中的狀態。javascript
Cookie 是服務器端發送給客戶端的一段特殊信息,這些信息以文本的方式存放在客戶端,客戶端每次向服務器端發送請求時都會帶上這些特殊信息。
具體過程是:客戶端發送請求到服務端,而後服務端返回的response headers中會有Set-Cookie這個字段,將 信息寫入 Cookie 中。而後在下一次客戶端請求接口時,會在request headers裏帶上這個Cookie字段,這樣服務器就能夠拿到這些信息,達到了維持狀態的目的。
前端
Cookie 主要用於如下三個方面:java
domain 指定了該 Cookie 所屬的域名,默認狀況下,domain 會被設置爲建立該 Cookie 時所在的域名。若是不指定,默認爲 origin,不包含子域名。若是指定了Domain,則通常包含子域名。
例如,若是設置 Domain=mozilla.org,則 Cookie 也包含在子域名中(如developer.mozilla.org)。
而 path 則指定了該 Cookie 所屬的路徑,注意子路徑也會被匹配。
例如,設置 Path=/docs,則/docs/Web/ 這個地址也會匹配。
domain 和 path 二者一塊兒來限制了該 Cookie 容許被哪些 URL 訪問。ios
Expires :具體到期時間,UTC格式。若是沒有設置該選項,則默認有效期爲session,即會話cookie,這種cookie在瀏覽器關閉後就沒有了。面試
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Max-Age屬性指定從如今開始 Cookie 存在的秒數,好比60 * 60 * 24 * 365(即一年)。過了這個時間之後,瀏覽器就再也不保留這個 Cookie。
若是同時指定了Expires和Max-Age,那麼Max-Age的值將優先生效。chrome
SameSite: Cookie 容許服務器要求某個 cookie 在跨站請求時不會被髮送,從而能夠阻止跨站請求僞造攻擊(CSRF)。
SameSite 能夠有下面三種值:後端
大多數主流瀏覽器的SameSite的默認值已是Lax了。若是想要指定 Cookies 在同站、跨站請求都被髮送,如今須要明確指定 SameSite 爲 None。(因此不要再問爲何接口返回了Set-Cookie可是卻沒有設置成功了,大機率緣由在這裏,曾經遇到過。本地開發的話在chrome://flags中把SameSite by default cookies設爲Disabled便可解決,可正常開發,上線的話通常不會跨域,即不會出現這個問題,若是出現跨域就只能讓後端改了domain字段了)跨域
若是這個屬性設置爲true,意思就是告之瀏覽器該 cookie 毫不能經過 JavaScript 的 document.cookie 屬性訪問。能夠避免跨域腳本 (XSS) 攻擊。
(面試高頻)瀏覽器
標記爲 Secure的 Cookie 只應經過被 HTTPS 協議加密過的請求發送給服務端。服務器
// 直接使用document.cookie = 設置便可 document.cookie= "test=" + '123';
直接調用函數,例如let cookie = getCookie(); cookie.name即爲對應cookie。
// 讀取Cookie函數 function getCookie() { let cookieArr = document.cookie.split("; "); // 特別注意!cookie中的數據都是以分號加空格區分開 let obj = {}; cookieArr.forEach( v => { let arr = v.split("="); obj[arr[0]] = unescape(arr[1]); // unescape 解碼 }); return obj }
直接調用:delCookie("xxx");
//刪除Cookie function delCookie(name){ // 將 cookie 的 max-age 屬性設置 0 來實現對 cookie 的刪除 document.cookie = `${name}=;max-age=0`; }
在ios系統上面,設置Cookie爲漢字時會設置失敗,因此須要將漢字進行編碼,再儲存到Cookie,取出來的時候也須要解碼,encode:escape(),decode:unescape()。
更多文章以及分享請關注微信公衆號 前端er的分享,不止於前端,按期輸出一些技術知識、生活感想、理財知識等。