發現不少地方在介紹cookie的做用時,都喜歡使用購物車的例子,那咱們也不妨從這個例子開始提及。程序員
場景示例:有用戶a和b,都登錄了某個購物網站,此時若是兩個用戶都點擊了【查看購物車】按鈕,那麼此時服務器就同時收到了2個請求,請求的內容都是:「請告訴我個人購物車有什麼商品」。如今問題來了——服務器怎麼區分哪一個請求對應哪一個用戶呢?web
其實這就是常常看到的那句話http協議是無狀態的。爲何說無狀態呢,由於http
協議能夠當作一種簡單的應答模式:chrome
那麼服務端知道兩次訪問的客戶端是否是同一個嗎?顯然是母雞呀!數據庫
爲了解決這個問題,就要介紹今天的主角--Cookie。數組
能夠聯想一下生活中。咱們若是去一家生意火爆的火鍋店吃火鍋的場景(我突然有點想去吃個火鍋再回來寫了),這時若是有空座了,店員怎麼知道在門口等候的顧客應該輪到誰了呢?很簡單,在顧客等候以前,先發個號碼牌,後面根據號碼辨別身份。瀏覽器
?!!
緩存
看到這裏,是否是以爲有點餓了?啊呸,是否是以爲靈光乍現,上面說的問題和這個場景不是一模一樣嗎?因此,爲了可以讓會話能夠被識別,http中也引入了一個號碼牌——cookie
的機制。(會話這個詞出現地有點突兀,簡單解釋下:a用戶登陸購物網站以後,接下來發生的一系列請求,都應該屬於服務端與a的會話)安全
好了,原理大概說完了,那cookie
具體怎麼實現呢?很簡單,放在http
的頭部(headers)
。在前一篇講狀態碼時,已經稍稍涉獵了一點http
頭部的相關知識,簡單的來講http
的頭部是一個js對象,裏面存放了一系列的鍵值對(key:value)用來表示各類信息,http的【請求】和【響應】都有頭部,而cookie機制的實現,則是藉助了其中的兩個字段:Cookie和Set-Cookie,整個運行流程能夠分紅如下步驟:服務器
http
請求到服務端(我去告訴店員,我要吃火鍋了)在上述過程當中,可能同時也有其餘號碼牌的顧客在與服務員進行相似的交流過程,因爲服務員發給每一個顧客的號碼牌上的數字都是惟一的,因此沒必要懼怕弄混。cookie
cookie 的基本原理就是這麼簡單!
固然,在生活中吃完飯咱們就把號碼牌丟掉了,下次來吃從新取號就行;可是在http請求中,cookie能夠設置使用期限,好比說6個月後才過時。那麼客戶端接到這個內容後,就會把cookie緩存報本地的某個位置,以後若是訪問相同的站點,就能夠直接取出對應的cookie來使用。接下來咱們看個實際案例(又到了緊張刺激的舉例子環節,此次不只有例子,還有精美配圖,我以爲能夠點個贊再走~)。
首先,咱們打開chrome瀏覽器的【設置】-【內容設置】-【cookie】(也能夠在設置的頂部直接搜索),進入後能夠查看【全部的cookie和網站數據】,看看segmengt這一條數據。裏面一共有7個cookie,展開看詳細內容,能夠看到域名
,腳本可訪問
、到期時間
等屬性,
這些屬性後面再介紹,爲了看到整個流程,咱們先清除這個站點下的cookie
,固然也能夠直接ctrl+shift+n打開一個隱身模式來直接測試。(隱身模式不會記錄cookie,咳咳,我固然也是爲了學習寫代碼才發現這個功能的!)
而後咱們打開segment
站點,同時打開f12調試工具的network面板。能夠看到這個請求(能夠直接選doc
類型查看,或者搜索框裏搜segment.com
快速過濾),
能夠看到這就對面前面說的第一個步驟:客戶端發送請求,服務端響應並提供set-cookie(也就是發放號碼牌的步驟)。
接下來咱們登陸這個網站而且再次請求這個站點。此時響應頭裏已經再也不有供set-cookie字段,由於cookie已經被緩存了(能夠去前面的設置裏再看看),而請求頭裏多了一個cookie字段。(這就是使用號碼牌的步驟了)。
接下來咱們把面板的請求類型切換到xhr
,再點點頁面上的功能,好比收藏本文,或者給做者點贊、打賞(瘋狂暗示)等等。 能夠看到請求裏都帶上了cookie這個頭部。
直到cookie過時,或者下次咱們又手動刪除這個站點cookie以前,原有的cookie均可以繼續使用。
接下來咱們來講說set-cookie和cookie字段的具體內容。按照流程首先是來自服務端的set-cookie,直接copy一個前文的cookie下來,依此介紹:
set-cookie: test_cookie=CheckForPermission; expires=Mon, 25-Feb-2019 00:28:09 GMT; path=/; domain=.doubleclick.net
test_cookie=CheckForPermission
,表示這個cookie的鍵值對,每一個cookie都會有本身的名稱和值expires=Mon, 25-Feb-2019 00:28:09 GMT
表示cookie的有效期,這個值若是不指定,那麼默認值爲到瀏覽器關閉以前爲止 path=/
,將服務器上的某個文件目錄做爲cookie的使用對象(這麼抽象的解釋確定是書上說的),簡單的來講,是指定服務端有權限訪 問Cookie的路徑,例如/session/,表示只有/session/下才能夠訪問cookie,默認爲文檔所在的目錄。domain=.doubleclick.net
,表示cookie所在的域。默認爲建立cookie的域。也就是請求地址,好比前面的segment.com
secure
,這個屬性前面沒有,表示只在https安全通訊時才發送cookiehttpOnly
,這個屬性前面也沒有,是用來限制使用腳本訪問cookie的,設置了這個值後,沒法在瀏覽器客戶端使用js
的document.cookie
讀取Cookie內容(頁面內部是能夠訪問的),這個功能能夠用來防止xss攻擊中利用js劫持cookie。而cookie字段就簡單的多:一樣看一個實例:
cookie:HPSESSID=web2~a667ecfoft7u5e3umvgam3vs65; Hm_lvt_e23800c454aa573c0ccb16b52665ac26=1551052787; _ga=GA1.2.113018985.1551052787; _gid=GA1.2.1438865670.1551052787;
直接以鍵值對的形式發送須要的cookie,使用分號分割表示多個cookie。
使用cookie時,服務端會對發送來的cookie進行校驗,校驗的內容爲過時時間(expire)、域(domain)、路徑(path)、協議(是否secure),從而判斷cookie是否有效。若是服務端已經發出了一個cookie,以後想修改cookie的值怎麼辦呢?那就要建立一個同名的cookie進行覆蓋刪除。同名的要求是除了name和expire之外的屬性要和原來的cookie一致,不然會被看成不一樣的cookie保存。
從前面的介紹咱們至少能夠看出cookie至少有如下幾個優勢:
固然缺點也顯而易見:
大部分講cookie的文章都會提到這兩個例子,可是不多有具體的說明大概是怎麼實現的。這裏作下簡單的介紹。
假設某網站登陸時,提供了一個能夠勾選的【7天內免登陸】複選框,用戶勾選並正確登陸以後的流程大概是這樣的:
服務端接收請求後,建立一個id好比111,用於表示當前發送請求的客戶端,並存在服務端的某個位置,簡單點能夠認爲就存在一個名叫sessions
的數組裏面吧。以後,把這個id放在響應的set-cookie裏面返回。例如:
set-cookie:sessonId=111
同時,服務端設定數組sessions
中的保存的111在7天后刪除
客戶端收到這個cookie以後保存,以後再次訪問的時候都帶上這個cookie,服務端接收到cookie裏附帶的sessionId=111後,去sessions
數組查詢是否含有111,
(其實在上面已經悄咪咪的說了一丟丟session的內容,可是本着每次着重說明一個知識點、儘可能剝離無關內容的原則,依然不在本文插入session的相關知識)
本文已經屢次提到購物車了,可是細心的朋友能夠看到,這裏的前面添加了「未登陸」,那登陸時候爲何不用呢?由於咱們前面比較優缺點的時候,有提到cookie畢竟只能存儲在發送請求的那個客戶端設備,而電商網站通常是容許多終端登陸的(x寶,x貓,x夕夕等),若是使用cookie來保存登陸後的購物車內容,那更換設備的時候就沒法查到了,因此登陸狀態下的購物車通常是存到數據庫中的,只在離線的時候使用cookie的方式來處理比較合適。
核心思路:
js讀寫cookie的方法處處都有,隨便搜索下應該就能找到,本文仍是着重於說明cookie的原理,就不在此贅述了。
本文對cookie的原理和應用場景進行了說明,依然延續以往的「一篇文章只說一件事」的習慣(程序員的事,怎麼能叫偷懶呢,這叫模塊化封裝)。但願能對看完的同窗有所幫助(就算是隻收穫了表情包也是極好的)。順便說一下,前一篇文章彷佛效果不錯,騙到了不少收藏和點贊,很是開心(再次瘋狂暗示)
慣例:若是內容有錯誤的地方歡迎指出(以爲看着不理解不舒服想吐槽也徹底沒問題);若是有幫助,歡迎點贊和收藏,轉載請徵得贊成後著明出處,若是有問題也歡迎私信交流,主頁有郵箱地址