Cookie

概述

Cookie 是服務(wù)器保存在瀏覽器的一小段文本信息,每個(gè) Cookie 的大小一般不能超過4KB舱殿。瀏覽器每次向服務(wù)器發(fā)出請(qǐng)求沪袭,就會(huì)自動(dòng)附上這段信息。

Cookie 保存以下幾方面的信息枝恋。

  • Cookie 的名字
  • Cookie 的值
  • 到期時(shí)間
  • 所屬域名(默認(rèn)是當(dāng)前域名)
  • 生效的路徑(默認(rèn)是當(dāng)前網(wǎng)址)

舉例來說焚碌,如果當(dāng)前URL是[www.example.com](http://www.example.com/)十电,那么Cookie的路徑就是根目錄/。這意味著台盯,這個(gè)Cookie對(duì)該域名的根路徑和它的所有子路徑都有效静盅。如果路徑設(shè)為/forums蒿叠,那么這個(gè)Cookie只有在訪問[www.example.com/forums](http://www.example.com/forums)及其子路徑時(shí)才有效蚣常。

瀏覽器可以設(shè)置不接受 Cookie抵蚊,也可以設(shè)置不向服務(wù)器發(fā)送 Cookie贞绳。window.navigator.cookieEnabled屬性返回一個(gè)布爾值冈闭,表示瀏覽器是否打開 Cookie 功能。

document.cookie屬性返回當(dāng)前網(wǎng)頁(yè)的 Cookie号显。

// 讀取當(dāng)前網(wǎng)頁(yè)的所有cookie
var allCookies = document.cookie;

由于document.cookie返回的是分號(hào)分隔的所有 Cookie押蚤,所以必須手動(dòng)還原羹应,才能取出每一個(gè) Cookie 的值园匹。

var cookies = document.cookie.split(';');

for (var i = 0; i < cookies.length; i++) {
  // cookies[i] name=value形式的單個(gè)Cookie
}

document.cookie屬性是可寫的,可以通過它為當(dāng)前網(wǎng)站添加 Cookie掖桦。

document.cookie = 'fontSize=14';

Cookie 的值必須寫成key=value的形式枪汪。注意,等號(hào)兩邊不能有空格雀久。另外赖捌,寫入 Cookie 的時(shí)候越庇,必須對(duì)分號(hào)、逗號(hào)和空格進(jìn)行轉(zhuǎn)義(它們都不允許作為 Cookie 的值)唯欣,這可以用encodeURIComponent方法達(dá)到。

但是蟀拷,document.cookie一次只能寫入一個(gè) Cookie问芬,而且寫入并不是覆蓋,而是添加强戴。

document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie
// test1=hello;test2=world

document.cookie屬性讀寫行為的差異(一次可以讀出全部 Cookie骑歹,但是只能寫入一個(gè) Cookie)道媚,與服務(wù)器與瀏覽器之間的 Cookie 通信格式有關(guān)最域。瀏覽器向服務(wù)器發(fā)送 Cookie 的時(shí)候镀脂,是使用一行將所有 Cookie 全部發(fā)送薄翅。

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2
Accept: */*

上面的頭信息中,Cookie字段是瀏覽器向服務(wù)器發(fā)送的 Cookie僧凰。

服務(wù)器告訴瀏覽器需要儲(chǔ)存 Cookie 的時(shí)候训措,則是分行指定绩鸣。

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: cookie_name1=cookie_value1
Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT

上面的頭信息中纱兑,Set-Cookie字段是服務(wù)器寫入瀏覽器的 Cookie,一行一個(gè)捡多。

如果仔細(xì)看瀏覽器向服務(wù)器發(fā)送的 Cookie铐炫,就會(huì)意識(shí)到倒信,Cookie 協(xié)議存在問題鳖悠。對(duì)于服務(wù)器來說,有兩點(diǎn)是無法知道的憎账。

  • Cookie 的各種屬性,比如何時(shí)過期看政。
  • 哪個(gè)域名設(shè)置的 Cookie朴恳,因?yàn)?Cookie 可能是一級(jí)域名設(shè)的,也可能是任意一個(gè)二級(jí)域名設(shè)的允蚣。

Cookie 的屬性

服務(wù)器向?yàn)g覽器發(fā)送 Cookie 的時(shí)候于颖,除了 Cookie 本身的內(nèi)容,還有一些可選的屬性也是可以寫入的嚷兔,它們都必須以分號(hào)開頭森渐。

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

上面的Set-Cookie字段做入,用分號(hào)分隔多個(gè)屬性。它們的含義如下同衣。

(1)value 屬性

value屬性是必需的竟块,它是一個(gè)鍵值對(duì),用于指定Cookie的值耐齐。

(2)expires 屬性

expires屬性用于指定 Cookie 過期時(shí)間耸携。它的格式采用Date.toUTCString()的格式喜命。

如果不設(shè)置該屬性丧裁,或者設(shè)為null,Cookie只在當(dāng)前會(huì)話(session)有效催享,瀏覽器窗口一旦關(guān)閉票髓,當(dāng)前 Session 結(jié)束裆操,該 Cookie 就會(huì)被刪除吊骤。

瀏覽器根據(jù)本地時(shí)間茅郎,決定 Cookie 是否過期掌敬,由于本地時(shí)間是不精確的,所以沒有辦法保證 Cookie 一定會(huì)在服務(wù)器指定的時(shí)間過期芯杀。

(3)domain屬性

domain屬性指定 Cookie 所在的域名扶供,比如[example.com](http://example.com/).[example.com](http://example.com/)(這種寫法將對(duì)所有子域名生效)、[subdomain.example.com](http://subdomain.example.com/)

如果未指定,默認(rèn)為設(shè)定該Cookie的域名。所指定的域名必須是當(dāng)前發(fā)送Cookie的域名的一部分,比如當(dāng)前訪問的域名是[example.com](http://example.com/)阶牍,就不能將其設(shè)為[google.com](http://google.com/)磕瓷。只有訪問的域名匹配 domain 屬性硕盹,Cookie 才會(huì)發(fā)送到服務(wù)器仰剿。

(4)path 屬性

path屬性用來指定路徑誊酌,必須是絕對(duì)路徑(比如/瘟仿、/mydir),如果未指定,默認(rèn)為請(qǐng)求該 Cookie 的網(wǎng)頁(yè)路徑。

只有path屬性匹配向服務(wù)器發(fā)送的路徑拷邢,Cookie 才會(huì)發(fā)送。這里的匹配不是絕對(duì)匹配,而是從根路徑開始益涧,只要path屬性匹配發(fā)送路徑的一部分记舆,就可以發(fā)送御蒲。比如屑埋,path屬性等于/blog摘能,則發(fā)送路徑是/blog或者/blog/roll逻恐,Cookie都會(huì)發(fā)送挽拂。path屬性生效的前提是domain屬性匹配察署。

(5)secure 屬性

secure屬性用來指定Cookie只能在加密協(xié)議HTTPS下發(fā)送到服務(wù)器希太。

該屬性只是一個(gè)開關(guān)克饶,不需要指定值。如果通信是HTTPS協(xié)議誊辉,該開關(guān)自動(dòng)打開矾湃。

(6)max-age

max-age屬性用來指定Cookie有效期,比如60 * 60 * 24 * 365(即一年31536e3秒)堕澄。

(7)HttpOnly

HttpOnly屬性用于設(shè)置該Cookie不能被JavaScript讀取邀跃,詳見下文的說明。

以上屬性可以同時(shí)設(shè)置一個(gè)或多個(gè)蛙紫,也沒有次序的要求拍屑。如果服務(wù)器想改變一個(gè)早先設(shè)置的Cookie,必須同時(shí)滿足四個(gè)條件:Cookie的key坑傅、domain僵驰、pathsecure都匹配。也就是說唁毒,如果原始的Cookie是用如下的Set-Cookie設(shè)置的蒜茴。

Set-Cookie: key1=value1; domain=example.com; path=/blog

改變上面這個(gè) Cookie 的值,就必須使用同樣的Set-Cookie浆西。

Set-Cookie: key1=value2; domain=example.com; path=/blog

只要有一個(gè)屬性不同粉私,就會(huì)生成一個(gè)全新的 Cookie,而不是替換掉原來那個(gè) Cookie室谚。

Set-Cookie: key1=value2; domain=example.com; path=/

上面的命令設(shè)置了一個(gè)全新的同名 Cookie毡鉴,但是path屬性不一樣。下一次訪問[example.com/blog](http://example.com/blog)的時(shí)候秒赤,瀏覽器將向服務(wù)器發(fā)送兩個(gè)同名的 Cookie猪瞬。

Cookie: key1=value1; key1=value2

上面代碼的兩個(gè) Cookie 是同名的,匹配越精確的Cookie排在越前面入篮。

瀏覽器設(shè)置這些屬性的寫法如下陈瘦。

document.cookie = 'fontSize=14; '
  + 'expires=' + someDate.toGMTString() + '; '
  + 'path=/subdirectory; '
  + 'domain=*.example.com';

另外,這些屬性只能用來設(shè)置 Cookie潮售。一旦設(shè)置完成痊项,就沒有辦法讀取這些屬性的值。

刪除一個(gè) Cookie 的唯一方法是設(shè)置其expires為一個(gè)過去的日期酥诽。

document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';

上面代碼中鞍泉,名為fontSize的 Cookie 的值為空,過期時(shí)間設(shè)為1970年1月1月零點(diǎn)肮帐,就等同于刪除了這個(gè) Cookie咖驮。

Cookie 的限制

瀏覽器對(duì) Cookie 數(shù)量的限制边器,規(guī)定不一樣。目前托修,F(xiàn)irefox 是每個(gè)域名最多設(shè)置50個(gè) Cookie忘巧,而 Safari 和 Chrome 沒有域名數(shù)量的限制。

所有 Cookie 的累加長(zhǎng)度限制為4KB睦刃。超過這個(gè)長(zhǎng)度的 Cookie砚嘴,將被忽略,不會(huì)被設(shè)置涩拙。

由于 Cookie 可能存在數(shù)量限制际长,有時(shí)為了規(guī)避限制,可以將 Cookie 設(shè)置成下面的形式吃环。

name=a=b&c=d&e=f&g=h

上面代碼實(shí)際上是設(shè)置了一個(gè) Cookie也颤,但是這個(gè) Cookie 內(nèi)部使用&符號(hào),設(shè)置了多部分的內(nèi)容郁轻。因此翅娶,讀取這個(gè) Cookie 的時(shí)候,就要自行解析好唯,得到多個(gè)鍵值對(duì)竭沫。這樣就規(guī)避了 Cookie 的數(shù)量限制。

同源政策

瀏覽器的同源政策規(guī)定骑篙,兩個(gè)網(wǎng)址只要域名相同和端口相同蜕提,就可以共享 Cookie。

注意靶端,這里不要求協(xié)議相同谎势。也就是說,[http://example.com](http://example.com/)設(shè)置的Cookie杨名,可以被[https://example.com](https://example.com/)讀取脏榆。

Http-Only Cookie

設(shè)置 Cookie 的時(shí)候,如果服務(wù)器加上了HttpOnly屬性台谍,則這個(gè) Cookie 無法被 JavaScript 讀刃胛埂(即document.cookie不會(huì)返回這個(gè)Cookie的值),只用于向服務(wù)器發(fā)送趁蕊。

Set-Cookie: key=value; HttpOnly

上面的這個(gè) Cookie 將無法用 JavaScript 獲取坞生。進(jìn)行 AJAX 操作時(shí),XMLHttpRequest對(duì)象也無法包括這個(gè) Cookie掷伙。這主要是為了防止 XSS 攻擊盜取 Cookie是己。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市任柜,隨后出現(xiàn)的幾起案子赃泡,更是在濱河造成了極大的恐慌寒波,老刑警劉巖乘盼,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件升熊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡绸栅,警方通過查閱死者的電腦和手機(jī)级野,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粹胯,“玉大人蓖柔,你說我怎么就攤上這事》缇溃” “怎么了况鸣?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)竹观。 經(jīng)常有香客問我镐捧,道長(zhǎng),這世上最難降的妖魔是什么臭增? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任懂酱,我火速辦了婚禮,結(jié)果婚禮上誊抛,老公的妹妹穿的比我還像新娘列牺。我一直安慰自己,他們只是感情好拗窃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布瞎领。 她就那樣靜靜地躺著,像睡著了一般随夸。 火紅的嫁衣襯著肌膚如雪九默。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天逃魄,我揣著相機(jī)與錄音荤西,去河邊找鬼。 笑死伍俘,一個(gè)胖子當(dāng)著我的面吹牛邪锌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播癌瘾,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼觅丰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了妨退?” 一聲冷哼從身側(cè)響起妇萄,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蜕企,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后冠句,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轻掩,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年懦底,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唇牧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡聚唐,死狀恐怖丐重,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杆查,我是刑警寧澤扮惦,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站亲桦,受9級(jí)特大地震影響崖蜜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜烙肺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一纳猪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桃笙,春花似錦氏堤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至星著,卻和暖如春购笆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虚循。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工同欠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人横缔。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓铺遂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親茎刚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子襟锐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容