cookie從哪來到哪去

做者: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的字段。
    跨域


    服務器經過這個字段來告訴瀏覽器,它須要設置一個cookie,而後瀏覽器檢查一下要設置的內容是否知足瀏覽器定下的cookie的「條條框框」,若是知足那麼一個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);複製代碼

    而後咱們看看實際上瀏覽器發送出去的請求:


    咱們設置的cookie並無生效,而且chrome瀏覽器下咱們會看到一行報錯

    Refused to set unsafe header "Cookie"

    因此說,由於瀏覽器的安全限制,咱們不能本身隨便設置請求頭中的cookie。

cookies條條框框

一個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-attributegoodbye-csrf-samesite-to-the-rescue

    最後,這些全部的屬性值,一塊兒決定了一件事——這個cookie那個URL能夠能用。

參考文獻:
developers.livechatinc.com/blog/settin…
www.sjoerdlangkemper.nl/2016/04/14/…


歡迎關注DDFE
GITHUB:github.com/DDFE
微信公衆號:微信搜索公衆號「DDFE」或掃描下面的二維碼

相關文章
相關標籤/搜索