HTTP協議當初爲了讓協議儘可能簡潔,制定爲無狀態協議,即指每次request請求以前是相互獨立的,當前請求並不會記錄它的上一次請求信息。那麼問題來了,開發中常常須要用到狀態記錄,好比平常的登陸網站,不可能每次登陸都要客戶從新輸入密碼,這樣用戶體驗確定會不好,那如何讓無狀態的http協議將狀態記錄下來呢?
因而瀏覽器廠商發明了cookie來解決這個難題。
Cookie老是保存在客戶端中,按在客戶端中的存儲位置,可分爲內存Cookie和硬盤Cookie,設置了過時時間Expires(Cookie的幾個屬性之一)的Cookie會存儲在硬盤裏面,不一樣操做系統cookie的儲存路徑會有所不一樣,而沒有設置該屬性的Cookie會存儲在內存裏面,此時瀏覽器的選項卡能夠共享同一個cookie信息,關閉瀏覽器就會清除該Cookie!
首先看一下cookie在先後端交互中的應用:
正則表達式
第一次驗證成功後,服務端會在響應頭信息中帶上「set-cookie」字段,瀏覽器監測到該字段以後,會把其中的值對號入座寫入瀏覽器的cookie的屬性中npm
存儲在cookie中的數據,在它過時以前,每次都會被瀏覽器自動放在http請求中,若是這些數據並非每一個請求都須要發給服務端的數據,瀏覽器這設置自動處理無疑增長了網絡開銷;但若是這些數據是每一個請求都須要發給服務端的數據(好比身份認證信息),瀏覽器這設置自動處理就大大免去了重複添加操做。因此對於那設置「每次請求都要攜帶的信息(最典型的就是身份認證信息token)」就特別適合放在cookie中。而服務器端經過驗證cookie中的信息,實現了驗證,也讓瀏覽器端省去了每次都須要輸入登陸信息的麻煩。後端
爲了實現cookie的做用,除了name和value以外,設計者還給它增長了七個屬性,分別是expires/max-age、domain、path、secure、HttpOnly、samesite,這些屬性是經過cookie選項來設置的,在設置任一個cookie時均可以設置相關的這些屬性,固然也能夠不設置,這時會使用這些屬性的默認值。瀏覽器
Expires和Max-Age
expires選項用來設置「cookie 什麼時間內有效」。expires實際上是cookie失效日期,expires必須是 GMT 格式的時間(能夠經過new Date().toGMTString()或者 new Date().toUTCString() 來得到)。
如expires=Thu, 25 Feb 2016 04:18:00 GMT表示cookie講在2016年2月25日4:18分以後失效,對於失效的cookie瀏覽器會清空。若是沒有設置該選項,則默認有效期爲session,即會話cookie。這種cookie在瀏覽器關閉後就沒有了,屬於內存cookie。而max-age就是cookie寫入以後的有效時長,好比max-age=600就是600秒後,cookie則會失效。max-age的優先級高於expires安全
domain 和 path
domain是域名,path是路徑,二者加起來就構成了 URL,domain和path一塊兒來限制 cookie 能被哪些 URL 訪問,domain屬性的默認值是建立cookie的網頁所在服務器的主機名。不能將一個cookie的域設置成服務器所在的域以外的域,要想cookie在多個二級域名中共享,須要設置domain爲頂級域名。服務器
HttpOnly
告知瀏覽器不容許經過腳本document.cookie去更改這個值,一樣這個值在document.cookie中也不可見。但在http請求張仍然會攜帶這個cookie。注意這個值雖然在腳本中不可獲取,但仍然在瀏覽器安裝目錄中以文件形式存在。cookie
secure
安全標誌,指定後,只有在使用SSL連接(https)時候才能發送到服務器,若是是http連接則不會傳遞該信息。就算設置了secure 屬性也並不表明他人不能看到你機器本地保存的 cookie 信息,因此不要把重要信息放在cookie中。網絡
除了服務器端返回的set-cookie字段,瀏覽器端也能夠對cookie進行操做,有npm爲咱們封裝好的插件js-cookie: https://www.npmjs.com/package...,不過咱們仍是用原生方法手動實現一遍session
獲取cookie:
在控制檯輸入document.cookie,或者js代碼中console.log(document.cookie)能夠獲得下圖:
能夠看到,cookie是一個個鍵值對(「鍵=值」的形式)加上分號空格隔開組合而成, 形如: "name1=value1; name2=value2; name3=value3",能夠用正則表達式來提取等號後面的值dom
function getCookie(name) { var value = '; '+ document.cookie; var parts = value.split('; ' + name + '='); if(parts.length === 2) { return parts.pop().split(';').shift(); } }
寫入cookie
function setCookie (name, value, day) { if(day !== 0){ //當設置的時間等於0時,不設置expires屬性,cookie在瀏覽器關閉後刪除 var expires = day * 24 * 60 * 60 * 1000 var date = new Date(+new Date()+expires); document.cookie = name + "=" + escape(value) + ";expires=" + date.toUTCString() }else{ document.cookie = name + "=" + escape(value) } }
注意:expires使用GMT或UTC格式的時間, 我這裏沒有指定路徑(path)和域(domain), 當沒有指定路徑時默認爲當前路徑下,如對 於「https://home.cnblogs.com/u/ma...」下設置的cookie,其path爲"/u/maderlzp", 其domain爲當前域名「home.cnblogs.com」
刪除cookie
設置cookie過時時間小於當前時間,那麼就會刪除該cookie
function deleteCookie(name) { document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;' }