解密Cookie,這一篇就夠了

1、Cookie介紹

由於HTTP協議是無狀態的,每次請求都是獨立的,服務器端沒法判斷兩次請求是否來自同一個用戶,進而也就沒法判斷用戶的登陸狀態,也不知道用戶上一次作了什麼。因此Cookie就是用來繞開HTTP的無狀態性的「額外手段」之一。服務器能夠設置或讀取Cookies中包含信息,藉此維護用戶跟服務器會話中的狀態。javascript

Cookie 是服務器端發送給客戶端的一段特殊信息,這些信息以文本的方式存放在客戶端,客戶端每次向服務器端發送請求時都會帶上這些特殊信息。
具體過程是:客戶端發送請求到服務端,而後服務端返回的response headers中會有Set-Cookie這個字段,將 信息寫入 Cookie 中。而後在下一次客戶端請求接口時,會在request headers裏帶上這個Cookie字段,這樣服務器就能夠拿到這些信息,達到了維持狀態的目的。
屏幕快照 2020-10-21 14.43.46.png屏幕快照 2020-10-21 14.43.33.png前端

Cookie 主要用於如下三個方面:java

  • 會話狀態管理(如用戶登陸狀態、購物車、遊戲分數或其它須要記錄的信息)
  • 個性化設置(如用戶自定義設置、主題等)
  • 瀏覽器行爲跟蹤(如跟蹤分析用戶行爲等)

2、Cookie的屬性

2.1 domain和path屬性

domain 指定了該 Cookie 所屬的域名,默認狀況下,domain 會被設置爲建立該 Cookie 時所在的域名。若是不指定,默認爲 origin,不包含子域名。若是指定了Domain,則通常包含子域名。
例如,若是設置 Domain=mozilla.org,則 Cookie 也包含在子域名中(如developer.mozilla.org)。
而 path 則指定了該 Cookie 所屬的路徑,注意子路徑也會被匹配。
例如,設置 Path=/docs,則/docs/Web/ 這個地址也會匹配。
domain 和 path 二者一塊兒來限制了該 Cookie 容許被哪些 URL 訪問。ios

2.2 Expires/Max-Age

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

  • Max-Age爲正數: cookie 會在 max-age 秒以後被銷燬
  • Max-Age爲負數時: cookie 只在瀏覽器會話期間存在,當用戶關閉瀏覽器窗口後這些值也會隨之銷燬
  • Max-Age 爲 0 時: cookie 將被當即銷燬

2.3 SameSite屬性

SameSite: Cookie 容許服務器要求某個 cookie 在跨站請求時不會被髮送,從而能夠阻止跨站請求僞造攻擊(CSRF)。
SameSite 能夠有下面三種值:後端

  • None。瀏覽器會在同站請求、跨站請求下繼續發送 cookies,不區分大小寫。
  • Strict。瀏覽器將只發送相同站點請求的 Cookie(即當前網頁 URL 與請求目標 URL 徹底一致)。
  • Lax。在新版本瀏覽器中,爲默認選項,Same-site Cookies 將會爲一些跨站子請求保留,如圖片加載或者 iframe 不會發送,而點擊 a 標籤會發送;

大多數主流瀏覽器的SameSite的默認值已是Lax了。若是想要指定 Cookies 在同站、跨站請求都被髮送,如今須要明確指定 SameSite 爲 None。(因此不要再問爲何接口返回了Set-Cookie可是卻沒有設置成功了,大機率緣由在這裏,曾經遇到過。本地開發的話在chrome://flags中把SameSite by default cookies設爲Disabled便可解決,可正常開發,上線的話通常不會跨域,即不會出現這個問題,若是出現跨域就只能讓後端改了domain字段了)跨域

2.4 HttpOnly

若是這個屬性設置爲true,意思就是告之瀏覽器該 cookie 毫不能經過 JavaScript 的 document.cookie 屬性訪問。能夠避免跨域腳本 (XSS) 攻擊。
(面試高頻)瀏覽器

2.5 Secure

標記爲 Secure的 Cookie 只應經過被 HTTPS 協議加密過的請求發送給服務端。服務器

3、Cookie相關操做

1.建立Cookie:

// 直接使用document.cookie = 設置便可
document.cookie= "test=" + '123';

2.讀取Cookie:

直接調用函數,例如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
}

3.刪除Cookie:

直接調用:delCookie("xxx");

//刪除Cookie
	function delCookie(name){
    // 將 cookie 的 max-age 屬性設置 0 來實現對 cookie 的刪除
		document.cookie = `${name}=;max-age=0`;
	}

在ios系統上面,設置Cookie爲漢字時會設置失敗,因此須要將漢字進行編碼,再儲存到Cookie,取出來的時候也須要解碼,encode:escape(),decode:unescape()。

4、其餘

  • Cookie是跨域的,也就是在不一樣的域名中,訪問的Cookie的時候,只能訪問對應的域名的Cookie。
  • 每一個Cookie的大小通常不超過4KB,超過之後,Cookie將會被忽略,不會被設置
  • 瀏覽器每次向服務器發起請求,就會自動附上Cookie

更多文章以及分享請關注微信公衆號 前端er的分享,不止於前端,按期輸出一些技術知識、生活感想、理財知識等。

相關文章
相關標籤/搜索