HTTP Cookie
般贼,通常直接叫做cookie
,最初是在客戶端用于存儲會話信息的遥诉。該標準要求服務器對任意HTTP
請求發(fā)送Set-Cookie HTTP
頭作為響應的一部分碍遍,其中包含會話信息。例如改基,這種服務器響應頭可能如下:
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
Other-header: other-header-value
這個HTTP
響應設置以name
為名稱繁疤,以value
為值的一個cookie
,名稱和值在傳送時都必須是URL
編碼的秕狰。瀏覽器會存儲這樣的會話信息稠腊,并在這之后,通過為每個請求添加Cookie HTTP
頭將信息發(fā)送回服務器鸣哀。如下所示:
GET /index.html HTTP/1.1
Cookie: name=value
Other-header: other-header-value
發(fā)送回服務器的額外信息可以用于唯一驗證客戶來自于發(fā)送的哪個請求架忌。
限制
cookie
在性質(zhì)上是綁定在特定的域名下的。當設定了一個cookie
后我衬,再給創(chuàng)建它的域名發(fā)送請求時鳖昌,都會包含這個cookie
。這個限制確保了儲存在cookie
中的信息只能讓批準的接受者訪問低飒,而無法被其他域訪問。
由于cookie
是存在客戶端計算機上的懂盐,還加入了一些限制確保cookie
不會被惡意使用褥赊,同時蛇占有太多磁盤空間。每個域的cookie
總數(shù)是有限的莉恼,不過瀏覽器之間各有不同拌喉。
當超過單個域名限制之后還要設置cookie
,瀏覽器就會清楚以前設置的cookie
俐银,IE
和Opera
會刪除最近最少使用過的(LRU
尿背,Least Recently Used
)cookie
。Firefox
看上去好像是隨機決定要清楚哪個cookie
捶惜,所以考慮cookie
限制非常重要田藐,以免出現(xiàn)不可預期的后果。
瀏覽器中對于cookie
的尺寸也有限制。大多數(shù)瀏覽器都有大約4096B(加減1)
的長度限制汽久。為了最佳的瀏覽器兼容性鹤竭,最好將整個cookie
長度限制在4095B
以內(nèi)。尺寸限制影響到一個域下所有的cookie
景醇,而并非每個cookie
單獨限制臀稚。
如果嘗試創(chuàng)建超過最大尺寸限制cookie
,那么該cookie
會被悄無聲息的丟掉三痰。注意吧寺,雖然一個字符通常占用一字節(jié),但是多字節(jié)情況則有不同散劫。
cookie的構成
cookie
由瀏覽器保存的以下幾塊信息構成稚机。
- 名稱:一個唯一確定
cookie
的名稱。cookie
名稱是不區(qū)分大小寫的舷丹,所以myCookie
和MyCookie
被認為是同一個cookie
抒钱。然而,實踐中最好將cookie
名稱看作是區(qū)分大小寫的颜凯,因為某些服務器會這樣處理cookie
谋币,cookie
的名稱必須是經(jīng)過URL
編碼的。 - 值:儲存在
cookie
里的字符串值症概。值必須被URL
編碼蕾额。 - 域:
cookie
對哪個域是有效的。所有向該域發(fā)送的請求中都會包含這個cookie
信息彼城。這個值可以包含子域诅蝶,也可以不包含它。如果沒有明確設定募壕,那么這個域會被人做來自設置cookie
的那個域调炬。 - 路徑:對于指定域中的那個路徑,應該向服務器發(fā)送
cookie
舱馅。例如缰泡,你可以指定cookie
只有從http://www.wrox.com/books/
中才能訪問,那么http://www.wrox.com
的頁面就不會發(fā)送cookie
信息代嗤,即使請求都是來自同一個域的棘钞。 - 失效時間:表示
cookie
何時應該被刪除的時間戳(也就是,何時應該停止向服務器發(fā)送這個cookie
)干毅。默認情況下宜猜,瀏覽器會話結束時即將所有cookie
刪除;不過也可以自己設置刪除時間硝逢。這個值是GMT
格式的日期姨拥,用于指定應該刪除cookie
的精確時間绅喉。因此,cookie
可以在瀏覽器關閉后依然保存在用戶的機器上垫毙。如果你設置的失效日期是個以前的時間霹疫,那么cookie
則會被立刻刪除。 - 安全標志: 指定后综芥,
cookie
只有在使用SSL
連接的時候才發(fā)送到服務器丽蝎。
每一段信息都作為Set-Cookie
頭的一部分,使用分號加空格分隔每一段膀藐,如下例所示屠阻。
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com
Other-header: other-header-value
該頭信息指定了一個叫做name
的cookie
,它會在格林威治時間2007年1月22日7:10:24失效额各,同時對于www.wrox.com
和wrox.com
的任何子域都有效国觉。
secure
標志是cookie
中唯一一個非名值對兒的部分,直接包含一個secure
單詞虾啦。如下:
HTTP/1.1 200 OK
Content-type: text/html
Set-cookie: name=value; domain=.wrox.com; path=/; secure
這里麻诀,創(chuàng)建了一個對于所有wrox.com
的子域和域名下(由path
參數(shù)指定的)所有頁面都有效的cookie
,因為設置了secure
標志傲醉,這個cookie
只能通過SSL
連接才能傳輸蝇闭。
尤其要注意,域硬毕、路徑呻引、失效時間和secure
標志都是服務器給瀏覽器的指示,以指定合適應該發(fā)送cookie
吐咳,這些參數(shù)并不會作為發(fā)送到服務器的cookie
信息的一部分逻悠,只有名值對兒才會被發(fā)送。
JS中的cookie
在JS中處理cookie
有些復雜韭脊,因為其眾所周知的蹩腳接口童谒,即BOM
的document.cookie
屬性。這個屬性的獨特之處在于它會因為使用它的方式不同表現(xiàn)出不同的行為沪羔。當用來獲取屬性值時饥伊,document.cookie
返回當前頁面可用的(根據(jù)cookie
的域、路徑任内、失效時間和安全設置)所有cookie
字符串,一系列由分號隔開的名值對兒融柬,如下所示死嗦。
name1 = value1; name2 = value2; name3 = value3;
所有名字和值都是經(jīng)過URL
編碼的,所以必須使用decodeURIComponent()
來解碼粒氧。
當用于設置值得時候越除,document.cookie
屬性可以設置為一個新的cookie
字符串。這個cookie
字符串會被解釋并添加到現(xiàn)有的cookie
集合中。設置document.cookie
并不會覆蓋cookie
摘盆,除非設置的cookie
的名稱已經(jīng)存在翼雀。設置cookie
的格式如下,和Set-Cookie
頭中使用的格式一樣孩擂。
name = value; expires = expiration_time; path = domain_path; domain = domain_name; secure
這些參數(shù)中狼渊,只有cookie
的名字和值是必需的,下面是一個簡單的例子类垦。
document.cookie = 'name = Ann';
這段代碼創(chuàng)建了一個叫name
的cookie
狈邑,值為Ann
。當客戶端每次向服務器端發(fā)送請求的時候蚤认,都會發(fā)送這個cookie
米苹,當瀏覽器關閉的時候,它就會被刪除砰琢。雖然這段代碼沒問題蘸嘶,但因為這里恰好名稱和值都無需編碼,所以最好每次設置cookie
時都使用encodeURIComponent()
陪汽。
document.cookie = encodeURIComponent('name') + '=' + encodeURIComponent('Ann');
要給被創(chuàng)建的cookie
指定額外的信息训唱,只要將參數(shù)追加到該字符串,和Set-Cookie
頭中的格式一樣掩缓,如下所示雪情。
document.cookie = encodeURIComponent('name') + '=' + encodeURIComponent('Ann') + '; domain=.wrox.com; path=/';
HTTP專有cookie
還有一類cookie
被稱為“HTTP
專有cookie
”。HTTP
專有cookie
可以從瀏覽器或者服務器設置你辣,但是只能從服務器端讀取巡通,因為JS無法獲取HTTP
專有cookie
的值。
由于所有的cookie
都會由瀏覽器作為請求頭發(fā)送舍哄,所以在cookie
中存儲大量信息會影響到特定域的請求性能宴凉。cookie
信息越大,完成對服務器請求的時間也就越長表悬。盡管瀏覽器對cookie
進行了大小限制弥锄。不過最好還是盡可能在cookie
中少存儲信息,以避免影響性能蟆沫。
Tips
一定不要在cookie
中存儲重要和敏感的數(shù)據(jù)籽暇。cookie
數(shù)據(jù)并非存儲在一個安全環(huán)境中,其中包含的任何數(shù)據(jù)都可以被他人訪問饭庞。所以不要在cookie
總存儲如信用卡號或者個人地址之類的數(shù)據(jù)戒悠。