做者:Jjavascript
瀏覽器添加cookie的時機:java
有客戶端來設置:經過javascript的api——document.cookie來操做git
document.cookie = 'name=value; maxAge=3000; path=/; domain=xx.com; secure'複製代碼
cookie的名和值中不能出現分號、逗號、等號和空格,每個key之間經過分號和空格來分割。github
經過document.cookie的方式來設置cookie每次只能設置一個cookie。若是咱們寫多個會有什麼效果呢?ajax
document.cookie = 'cookie1=value1; cookie2=value2'複製代碼
放在console中運行一下,會發現,只有第一個cookie1設置成功,而cookie2被無視了。因此要設置多個cookie,最簡單的方式就是屢次調用document.cookie。chrome
由服務端來設置:http的響應頭中。api
打開瀏覽器的控制檯,在network下咱們能夠看到瀏覽器發出的全部請求。這些請求的返回頭中,有些會發現一個Set-Cookie的字段。
跨域
在上圖中,響應頭裏set-cookie字段能夠有多個,每個對應一個要設置的cookie,且只能對應一個。瀏覽器
客戶端主動獲取安全
和客戶端設置相同,獲取的時候也是經過document.cookie來讀取:
var cookies = document.cookie複製代碼
讀取到的cookie爲一串字符串,每一個cookie之間經過分號來分割。
隨着請求發送
瀏覽器發送請求時,在請求的頭中會自動將「符合條件」的cookie帶上。
既然是請求頭中攜帶的,那麼咱們經過ajax發送請求的時候,可否順便設置一下cookie呢?簡單的實驗一下便可知曉:
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', "key=value");
xhr.send(null);複製代碼
而後咱們看看實際上瀏覽器發送出去的請求:
Refused to set unsafe header "Cookie"
因此說,由於瀏覽器的安全限制,咱們不能本身隨便設置請求頭中的cookie。
一個cookie除了value外,還有domain、path、expires/max-age、httpOnly、secure、sameSite這些屬性。設置cookie的時候,能夠對這些相關屬性進行設置,固然也能夠不進行設置,這時瀏覽器會自動給這些屬性一個默認值。cookie的條條框框就和這些屬性脫不了干係。
domain
domain限制了cookie的使用範圍:只能在domain值的範圍中才能訪問到該cookie.
同時domain值的設置也有嚴格的要求。
自身
毫無疑問domain的值能夠設置爲自己。
向下:全部子域名
若是咱們當前頁面的域名是 sub.test.com, 那麼 domain 能夠設置爲.sub.test.com。容許全部sub.test.com的子域名訪問,如xx.sub.test.com、xx.xx.sub.test.com。
向上:父級域名,直到Top-Level的下一級
若是咱們當前頁面的域名是sub.test.com, 那麼domain能夠設置爲test.com。可是不能設置爲.com。由於.com屬於Top-Level Domain。
path
domain+path 共同限制了可訪問該cookie的URL。若是某個cookie的path='/home',那麼只有「domain/home」下的全部url能夠訪問該cookie。
expires/max-age
這兩個值決定了cookie能活多久。若是不進行設置,那麼瀏覽器會默認將cookie的有效期設置爲 session,當頁面關閉後cookie便隨之被清理了。若是但願cookie在頁面關閉後,仍然能保存一段時間,那麼就須要爲cookie設置一個過時時間,在過時時間內瀏覽器都會爲咱們保留該cookie.
expires 是 http/1.0協議中的選項,在新的http/1.1協議中expires已經由 max-age 選項代替。expires必須是 GMT 格式的時間。
max-age的單位爲秒,cookie失效時刻 = 建立時刻 + max-age
httpOnly
若是一個cookie被標記爲httpOnly, 那麼前文所提到的經過document.cookie的方式就沒法獲取到該cookie。一樣的,咱們經過js來設置cookie的,也沒法被標記爲httpOnly。也就說如下寫法是不會生效的:
document.cookie="cookie1=value1; HttpOnly"複製代碼
這個值只能經過請求的響應頭來設置。默認狀況下,cookie不會帶httpOnly選項。
Secure
對於被標記爲Secure的cookie,只有當請求是HTTPS或者其餘安全協議時,該cookie 才能被訪問到。一樣的,也只有在HTTPS或者其餘安全協議時,咱們也才能經過js設置secure的cookie。
sameSite
這個值這是谷歌開發的一種安全機制,用來定義cookie如何跨域發送,其目的是嘗試阻止CSRF。chrome51版本已經支持。關於各大瀏覽器的支持狀況,參考chrome官網。關於這個特性,這裏很少作介紹了,感興趣的可參看preventing-csrf-with-samesite-cookie-attribute和goodbye-csrf-samesite-to-the-rescue
最後,這些全部的屬性值,一塊兒決定了一件事——這個cookie那個URL能夠能用。
參考文獻:
developers.livechatinc.com/blog/settin…
www.sjoerdlangkemper.nl/2016/04/14/…
歡迎關注DDFE
GITHUB:github.com/DDFE
微信公衆號:微信搜索公衆號「DDFE」或掃描下面的二維碼