把cookie聊清楚

laihuamin發表於2017-10-02

前言

cookie在web開發中時常被用到,也是面試官喜歡問的一塊技術,很多人或許和我以前一樣,只知其一不知其二,談起web儲存,都會答localStorage、sessionStorage、還有就是cookie,然後一些區別啊什麼的倒背如流,cookie的優缺點也瞭然於心,但是當你看完這塊內容之後,你會對cookie有另外獨到的見解,希望以後問到這塊技術,或者專案中遇到這個你都會處理,我在實習的過程中,一直在用,所以它真的不是口頭說說的那麼簡單,讓我們進入cookie的世界

這個講起來很簡單,瞭解http的同學,肯定知道,http是一個不儲存狀態的協議,什麼叫不儲存狀態,就是一個伺服器是不清楚是不是同一個瀏覽器在訪問他,在cookie之前,有另外的技術是可以解決,這裡簡單講一下,就是在請求中插入一個token,然後在傳送請求的時候,把這個東西帶給伺服器,這種方式是易出錯,所以有了cookie的出現

cookie
cookie

cookie是什麼,cookie就是一種瀏覽器管理狀態的一個檔案,它有name,也有value,後面那些看不見的是Domain、path等等,我們後面會介紹

cookieSend
cookieSend

第一次訪問網站的時候,瀏覽器發出請求,伺服器響應請求後,會將cookie放入到響應請求中,在瀏覽器第二次發請求的時候,會把cookie帶過去,服務端會辨別使用者身份,當然伺服器也可以修改cookie內容

我就幾個例子你就懂了,當我開啟百度的網頁,我要設定一個cookie的時候,我的指令如下

javascript:document.cookie='myname=laihuamin;path=/;domain=.baidu.com';複製程式碼
javascript:document.cookie='myname=huaminlai;path=/;domain=.google.com';複製程式碼

當我將這兩個語句都放到瀏覽器控制檯執行的時候,你會發現一點,注意,上面兩個cookie的值是不相同的,看清楚

cookieDontDomain
cookieDontDomain

顯而易見的是,真正能把cookie設定上去的只有domain是.baidu.com的cookie繫結到了域名上,所以上面所說的不可跨域性,就是不能在不同的域名下用,每個cookie都會繫結單一的域名

cookie的屬性眾多,我們可以來看一下下面這張圖,然後我們一個一個分析

cookieAttr
cookieAttr

name

這個顯而易見,就是代表cookie的名字的意思,一個域名下繫結的cookie,name不能相同,相同的name的值會被覆蓋掉,有興趣的同學可以試一試,我在專案中切實用到過

value

這個就是每個cookie擁有的一個屬性,它表示cookie的值,但是我在這裡想說的不是這個,因為我在網上看到兩種說法,如下:

1.cookie的值必須被URL編碼

2.對cookie的值進行編碼不是必須的,還舉了原始文件中所說的,僅對三種符號必須進行編碼:分號、逗號和空格

這個東西得一分為二來看,先看下面的圖

cookievalue
cookievalue

我在網上看到那麼一種說法:

由於cookie規定是名稱/值是不允許包含分號,逗號,空格的,所以為了不給使用者到來麻煩,考慮伺服器的相容性,任何儲存cookie的資料都應該被編碼。

domain

這個是指的域名,這個代表的是,cookie繫結的域名,如果沒有設定,就會自動繫結到執行語句的當前域,還有值得注意的點,統一個域名下的二級域名也是不可以交換使用cookie的,比如,你設定www.baidu.com和image.baidu.com,依舊是不能公用的

path

path這個屬性預設是'/',這個值匹配的是web的路由,舉個例子:

//預設路徑
www.baidu.com
//blog路徑
www.baidu.com/blog複製程式碼

我為什麼說的是匹配呢,就是當你路徑設定成/blog的時候,其實它會給/blog、/blogabc等等的繫結cookie

cookieMaxAge
cookieMaxAge

什麼是有效期,就是圖中的Expires屬性,一般瀏覽器的cookie都是預設儲存的,當關閉瀏覽器結束這個會話的時候,這個cookie也就會被刪除,這就是上圖中的——session(會話儲存)。

如果你想要cookie存在一段時間,那麼你可以通過設定Expires屬性為未來的一個時間節點,Expires這個是代表當前時間的,這個屬性已經逐漸被我們下面這個主人公所取代——Max-Age

Max-Age,是以秒為單位的,Max-Age為正數時,cookie會在Max-Age秒之後,被刪除,當Max-Age為負數時,表示的是臨時儲存,不會生出cookie檔案,只會存在瀏覽器記憶體中,且只會在開啟的瀏覽器視窗或者子視窗有效,一旦瀏覽器關閉,cookie就會消失,當Max-Age為0時,又會發生什麼呢,刪除cookie,因為cookie機制本身沒有設定刪除cookie,失效的cookie會被瀏覽器自動從記憶體中刪除,所以,它實現的就是讓cookie失效。

secure

cookieSecure
cookieSecure

這個屬性譯為安全,http不僅是無狀態的,還是不安全的協議,容易被劫持,打個比方,你在手機端瀏覽網頁的時候,有沒有中國移動圖示跳出來過,閒言少敘,當這個屬性設定為true時,此cookie只會在https和ssl等安全協議下傳輸

  • 提示:這個屬性並不能對客戶端的cookie進行加密,不能保證絕對的安全性

HttpOnly

這個屬性是面試的時候常考的,如果這個屬性設定為true,就不能通過js指令碼來獲取cookie的值,能有效的防止xss攻擊,看MDN的官方文件:

httpOnly
httpOnly

document.cookie可以對cookie進行讀寫,看一下兩條指令:

//讀取瀏覽器中的cookie
console.log(document.cookie);
//寫入cookie
document.cookie='myname=laihuamin;path=/;domain=.baidu.com';複製程式碼

關於怎麼設定cookie,我們只要開啟控制檯,看一個http的請求頭和響應頭中的東西即可明白:

setCookie
setCookie

服務端就是通過setCookie來設定cookie的,注意點,要設定多個cookie時,得多寫幾個setCookie,我們還可以從上圖看到,請求可以攜帶cookie給後端。

總結

cookie講了這麼多,自己也收穫了很多,也希望分享給大家,或許寫的不夠好,請見諒,如果覺得我寫的好的朋友,給個star,github地址

相關文章