當前位置:
首頁 > 最新 > 再好好聊一聊 HTTP 中的 Cookie 細節

再好好聊一聊 HTTP 中的 Cookie 細節

題圖:by Juan Pablo Arenas


一、序

Hi,大家好,我是承香墨影!

HTTP 協議在網路知識中佔據了重要的地位,HTTP 協議最基礎的就是請求和響應的報文,而報文又是由報文頭(Header)和實體組成。大多數 HTTP 協議的使用方式,都是依賴設置不同的 HTTP 請求/響應 的 Header 來實現的。

本系列《實用 HTTP》就拋開常規的 Header 講解式的表述方式,從實際問題出發,來分析這些 HTTP 協議的使用方式,到底是為了解決什麼問題?同時講解它是如何設計的和它實現原理。

HTTP 協議是一種無狀態的「鬆散協議」,它不會記錄不同請求的狀態,並且因為它本身包含了兩端(客戶端和服務端),根據請求和響應來區分,它大部分的內容都只是一個建議,其實雙邊是可以不遵守此建議的。

「這裡寫了建議零售價 2 元…」

「哦,不接受建議!」

文本是本系列的第四篇,前三篇傳送門:

本身 HTTP 就是一個無狀態的協議,但是有時候我們又有需要增加狀態的需求,這個時候延伸出來了 Cookie,利用 Cookie 可以讓傳輸的時候保持一些狀態信息。

本文就來講講 Cookie 的所有細節。


2.1 什麼是 Cookie?

先明確一點,Cookie 就是為了解決 HTTP 協議無狀態的問題,接下來舉個例子說明。

早年間醫院對患者的病例還沒有在線建檔的時候,都需要患者在就醫之前,辦理一個病歷的小冊子,醫生會在病歷中寫上此次就醫的情況,什麼時間、有什麼表現的反映、診斷是什麼病、開了一些什麼葯等等。如果下次又生病了,有病歷的情況下,都會要求患者再把病歷帶上,這樣醫生就能通過病歷了解到之前的情況。

在 Cookie 的實現上,也是這樣的。

服務端(醫生)在收到客戶端(患者)請求的時候,將一些用戶標識信息加入到 Cookie (病例)中,隨著響應返回給客戶端,客戶端將 Cookie 中的信息存儲在本地,下次再請求此伺服器的時候,再將 Cookie 中攜帶的數據原樣傳輸給服務端,此時服務端就能通過 Cookie 中的用戶標識,識別出這是之前請求過的某個用戶。

在這個例子中,服務端就是醫生的角色、客戶端是患者的角色、Cookie 就是病歷。

Netscape 官方文檔中的定義為:Cookie 是指在 HTTP 協議下,伺服器或腳本可以維護客戶端計算機上信息的一種方式 。通俗地說,Cookie 是一種能夠讓網站 Web 伺服器把少量數據儲存到客戶端的硬碟或內存里,或是從客戶端的硬碟里讀取數據的一種技術。 Cookie 文件則是指在瀏覽某個網站時,由 Web 伺服器的 CGI 腳本創建的存儲在瀏覽器客戶端計算機上的一個小文本文件。

2.2 一個完整的 Cookie 傳輸流程

HTTP 協議中的規則,都是通過在請求頭和響應頭中寫入輸入來實現,Cookie 也是這樣的。

服務端通過 這個響應頭來向客戶端中寫入 Cookie 信息,而客戶端讀取 這個響應頭中的信息存儲起來,在下次請求的時候取出來,再通過 這個請求頭,將 Cookie 的數據傳輸給服務端。

再看一個瀏覽器中,Cookie 使用的實例。

在響應頭(Response Header)中,使用傳遞不同的 Cookie 數據,多個數據可以分開成多個頭。

在請求頭中(Request Header)中,使用 這個請求頭傳遞 Cookie 數據,不同的數據通過 分割。

到這裡,我想你應該弄清楚了 cookie 的整個執行流程,接下來我們再來探究一些 cookie 的細節。

3.1 Cookie 的類型

cookie 其實都是存儲在客戶端,通常我們說 cookie 對應的客戶端,就是在說瀏覽器。

對於 cookie,我們可以簡單的將 cookie 分為兩類:

會話 cookie。

持久 cookie。

會話 cookie 是一種臨時的 cookie,用於存儲一些臨時的信息,存儲在內存中,會話 cookie 在用戶退出瀏覽器的時候,會被清空刪除。而持久 cookie 的生存周期會更長久一些,被存儲在磁碟上,瀏覽器重啟後它們依然存在,但是他們會有一個過期的時間,只在此時間之後會被置為失效。

會話 cookie 和持久 cookie 之間唯一的區別就是它們的過期時間,只要是設置了過期時間的 cookie 就是持久 cookie,反之則是會話 cookie。

仔細看前面的流程圖中,有一個 的欄位是用於標識當前 Cookie 支持的域名的,而想要設置過期時間,可以使用 或者 參數進行設置,有點類似我們前面講 HTTP 緩存的參數。

3.2 Cookie 的配置參數

到現在我們已經介紹了兩個 Cookie 配置的信息, 和 ,分別用來配置域名和過期策略。

這些都很好理解,畢竟瀏覽器是開放的,它會訪問很多不同的網址,如果每個請求都將所有的 Cookie 信息都傳遞過去,基本上是不現實的。而這些配置參數,就是對 Cookie 增加一些附加的設置,進行一些簡單的限制和過濾,在減少傳輸量的同時也保證了安全。

Domain 這個參數可以限制只在此域名下的請求,才傳遞該 Cookie,其他的不傳遞。

Cookie 其實還支持其他的一些參數配置,打開 Chrome 的調試模式,在 Application 中就可以看到當前頁面的 Cookie 信息。

這個表中,就是當前存儲的所有 Cookie 信息,而表頭,則是 Chrome 支持的 Cookie 信息。

下面我們分別來介紹它們。

Name:Value :Cookie 存儲的數據就是一個 Key-Value 的鍵值對,所以這兩個參數沒什麼爭議,就是數據的 Key 和 Value。

Domain:Cookie 的域,限制請求頭傳輸的域。

Path:域中與 Cookie 相關的路徑前綴。

Expires/Max-Age:過期時間或者超時間隔。

http:此屬性為 True,表示只會在 HTTP 請求頭中攜帶此 Cookie 信息,而無法通過 document.cookie 來訪問此 Cookie。

Secure:安全,是否只有在使用 SSL 連接時才發送這個 Cookie。

其實都很好理解,就不展開講解了。

3.3 Set-Cookie2 和 Cookie2

有些資料里會提到 和 ,這些都是歷史遺留問題,當初想對 Cookie 再進行一些功能上的擴展,但並未得到廣泛的實施,現在已經棄用了。

大家了解一下即可,有興趣可以參考 RFC 6265。

RFC 6265:

https://tools.ietf.org/html/rfc6265

3.4 瀏覽器對 Cookie 的限制

大部分時候我們聊到 Cookie 都在說的是伺服器和瀏覽器進行通信時候,而不同的瀏覽器對 Cookie 存儲的限制是不一樣的。例如:單個域名可存儲的 Cookie 數量、Cookie 大小等。

我簡單找了一些資料,來說明不同瀏覽器對 Cookie 的支持情況。

這些數據我沒有驗證過,但是也能說明不同瀏覽器對 Cookie 的支持情況。在進行頁面 Cookie 操作的時候,應該盡量保證 Cookie 的個數小於 20 個,總大小小於 4KB,這是一個安全且保險的範圍。


4.1 Cookie 安全

前面配置 Cookie 參數的時候,有兩個參數:http 和 secure 屬性,它們就在一定程度上保證了安全。

1.http 屬性

設置了 http 屬性,標識它是一個 「HttpOnly」 的,那麼通過一些腳本程序(例如 JS的 document.cookie)將無法讀取到這個 Cookie 信息,它只會出現在請求的報文頭內。

2.secure 屬性

secure 屬性強制該 Cookie 只有在 SSL 的環境下才會想伺服器傳輸,相對也保證了傳輸的安全。

4.2 Cookie 不支持跨域

Cookie 本身是不支持跨域的,一定程度也保證了 Cookie 的安全,如果非要跨域其實作為前端基本上能做的很少,大部分都需要服務端的二次配合。

例如:nginx 反向代理、Jsonp、nodejs 的 superagent、iframe 等方法。

有興趣再單獨了解就好了。


HTTP 中的 Cookie 知識點,基本上都已經講解清楚了,我們再次總結一下關鍵知識點。

1.Cookie 主要是為了解決 HTTP 協議無狀態的問題。

2.服務端通過 響應頭來向客戶端設置 Cookie。

3.客戶端通過 請求頭向服務端發送之前存儲的 Cookie 數據。

4.Cookie 依據過期時間進行區分,將類型分為:臨時 Cookie 和 持久 Cookie。

5.Cookie 可以通過配置不同的參數,進行限制,例如過期時間、支持的域名、是否安全(secure)等。

6.Cookie 不支持跨域,跨域還需要其他的方式繞開來實現。

7.Cookie 只能做到相對的安全,任何事情沒有絕對的安全。

參考:

Cookie 個數限制及大小:https://my.oschina.net/gaollg/blog/71299。

RFC 6265:https://tools.ietf.org/html/rfc6265

cookie 小結:http://www.cnblogs.com/xianyulaodi/p/6476991.html

「知識星期·聯機圓桌」一年 50 個優質問題,上桌聯機學習。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 承香墨影 的精彩文章:

看完《葯神》發現:當葯神救不了你的時候,你只能自救!
HTTP 內容編碼,也就這 2 點需要知道

TAG:承香墨影 |