什么是cookie碟渺,以及cookie 詳解

cookie是什么

cookie簡單來說就是由服務器產(chǎn)生按咒,存儲在客戶端的一個text類型文本。

為什么需要cookie

web程序是使用HTTP協(xié)議傳輸?shù)模鳫TTP協(xié)議是無狀態(tài)的協(xié)議,對于事務處理沒有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息已旧,則它必須重傳,這樣可能導致每次連接傳送的數(shù)據(jù)量增大

cookie 是怎么工作的

首先必須明確一點召娜,存儲cookie是瀏覽器提供的功能运褪。cookie 其實是存儲在瀏覽器中的純文本,瀏覽器的安裝目錄下會專門有一個 cookie 文件夾來存放各個域下設(shè)置的cookie玖瘸。

當網(wǎng)頁要發(fā)http請求時秸讹,瀏覽器會先檢查是否有相應的cookie,有則自動添加在request header中的cookie字段中雅倒。這些是瀏覽器自動幫我們做的嗦枢,而且每一次http請求瀏覽器都會自動幫我們做。這個特點很重要屯断,因為這關(guān)系到“什么樣的數(shù)據(jù)適合存儲在cookie中”文虏。

存儲在cookie中的數(shù)據(jù),每次都會被瀏覽器自動放在http請求中殖演,如果這些數(shù)據(jù)并不是每個請求都需要發(fā)給服務端的數(shù)據(jù)氧秘,瀏覽器這設(shè)置自動處理無疑增加了網(wǎng)絡(luò)開銷;但如果這些數(shù)據(jù)是每個請求都需要發(fā)給服務端的數(shù)據(jù)(比如身份認證信息)趴久,瀏覽器這設(shè)置自動處理就大大免去了重復添加操作丸相。所以對于那設(shè)置“每次請求都要攜帶的信息(最典型的就是身份認證信息)”就特別適合放在cookie中,其他類型的數(shù)據(jù)就不適合了彼棍。

但在 localStorage 出現(xiàn)之前灭忠,cookie被濫用當做了存儲工具膳算。什么數(shù)據(jù)都放在cookie中,即使這些數(shù)據(jù)只在頁面中使用而不需要隨請求傳送到服務端弛作。當然cookie標準還是做了一些限制的:每個域名下的cookie 的大小最大為4KB涕蜂,每個域名下的cookie數(shù)量在50個左右(不同瀏覽器數(shù)量不同)。

cookie 的格式

例如你可以直接在百度的調(diào)試模式下映琳,在控制臺輸入document.cookie


image.png

打印出的是一個字符串机隙,因為cookie本身就是存儲在瀏覽器中的字符串,由鍵值對 key=value構(gòu)成萨西,鍵值對之間由一個分號和一個空格隔開有鹿。

cookie 的屬性選項

每個cookie都有一定的屬性,如什么時候失效谎脯,要發(fā)送到哪個域名葱跋,哪個路徑等等。這些屬性是通過cookie選項來設(shè)置的源梭,cookie選項包括:expires娱俺、domain、path咸产、secure、HttpOnly仲闽。在設(shè)置任一個cookie時都可以設(shè)置相關(guān)的這些屬性脑溢,當然也可以不設(shè)置,這時會使用這些屬性的默認值赖欣。在設(shè)置這些屬性時屑彻,屬性之間由一個分號和一個空格隔開。代碼示例如下:

"key=name; expires=Thu, 25 Feb 2016 04:18:00 GMT; domain=ppsc.sankuai.com; path=/; secure; HttpOnly"
  • expires
    expires選項用來設(shè)置“cookie 什么時間內(nèi)有效”顶吮。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瀏覽器會清空搏恤。如果沒有設(shè)置該選項,則默認有效期為session湃交,即會話cookie熟空。這種cookie在瀏覽器關(guān)閉后就沒有了。

expires 是 http/1.0協(xié)議中的選項搞莺,在新的http/1.1協(xié)議中expires已經(jīng)由 max-age 選項代替息罗,兩者的作用都是限制cookie 的有效時間。expires的值是一個時間點(cookie失效時刻= expires)才沧,而max-age 的值是一個以秒為單位時間段(cookie失效時刻= 創(chuàng)建時刻+ max-age)迈喉。
另外绍刮,max-age 的默認值是 -1(即有效期為 session );若max-age有三種可能值:負數(shù)挨摸、0孩革、正數(shù)。負數(shù):有效期session油坝;0:刪除cookie嫉戚;正數(shù):有效期為創(chuàng)建時刻+ max-age

  • domain 和 path
    domain是域名,path是路徑澈圈,兩者加起來就構(gòu)成了 URL彬檀,domain和path一起來限制 cookie 能被哪些 URL 訪問。

一句話概括:某cookie的 domain為“baidu.com”, path為“/ ”瞬女,若請求的URL(URL 可以是js/html/img/css資源請求窍帝,但不包括 XHR 請求)的域名是“baidu.com”或其子域如“api.baidu.com”、“dev.api.baidu.com”诽偷,且 URL 的路徑是“/ ”或子路徑“/home”坤学、“/home/login”,則瀏覽器會將此 cookie 添加到該請求的 cookie 頭部中报慕。

所以domain和path2個選項共同決定了cookie何時被瀏覽器自動添加到請求頭部中發(fā)送出去深浮。如果沒有設(shè)置這兩個選項,則會使用默認值眠冈。domain的默認值為設(shè)置該cookie的網(wǎng)頁所在的域名飞苇,path默認值為設(shè)置該cookie的網(wǎng)頁所在的目錄。

特別說明1:
發(fā)生跨域xhr請求時蜗顽,即使請求URL的域名和路徑都滿足 cookie 的 domain 和 path布卡,默認情況下cookie也不會自動被添加到請求頭部中。若想知道原因請閱讀本文最后一節(jié))
特別說明2:
domain是可以設(shè)置為頁面本身的域名(本域)雇盖,或頁面本身域名的父域忿等,但不能是公共后綴 public suffix。舉例說明下:如果頁面域名為 www.baidu.com, domain可以設(shè)置為“www.baidu.com”崔挖,也可以設(shè)置為“baidu.com”贸街,但不能設(shè)置為“.com”或“com”。

  • secure

secure選項用來設(shè)置cookie只在確保安全的請求中才會發(fā)送狸相。當請求是HTTPS或者其他安全協(xié)議時匾浪,包含 secure 選項的 cookie才能被發(fā)送至服務器。

默認情況下卷哩,cookie不會帶secure選項(即為空)蛋辈。所以默認情況下,不管是HTTPS協(xié)議還是HTTP協(xié)議的請求,cookie 都會被發(fā)送至服務端冷溶。但要注意一點渐白,secure選項只是限定了在安全情況下才可以傳輸給服務端,但并不代表你不能看到這個 cookie逞频。
下面我們設(shè)置一個 secure類型的 cookie:

document.cookie = "name=huang; secure";

這里有個坑需要注意下:
如果想在客戶端即網(wǎng)頁中通過 js 去設(shè)置secure類型的 cookie纯衍,必須保證網(wǎng)頁是https協(xié)議的。在http協(xié)議的網(wǎng)頁中是無法設(shè)置secure類型cookie的苗胀。

  • httpOnly
    這個選項用來設(shè)置cookie是否能通過 js 去訪問襟诸。默認情況下,cookie不會帶httpOnly選項(即為空)基协,所以默認情況下歌亲,客戶端是可以通過js代碼去訪問(包括讀取、修改澜驮、刪除等)這個cookie的陷揪。當cookie帶httpOnly選項時,客戶端則無法通過js代碼去訪問(包括讀取杂穷、修改悍缠、刪除等)這個cookie。

在客戶端是不能通過js代碼去設(shè)置一個httpOnly類型的cookie的耐量,這種類型的cookie只能通過服務端來設(shè)置飞蚓。

——httpOnly與安全
從上面介紹中,大家是否會有這樣的疑問:為什么我們要限制客戶端去訪問cookie廊蜒?其實這樣做是為了保障安全趴拧。
試想:如果任何 cookie 都能被客戶端通過document.cookie獲取會發(fā)生什么可怕的事情。當我們的網(wǎng)頁遭受了 XSS 攻擊劲藐,有一段惡意的script腳本插到了網(wǎng)頁中八堡。這段script腳本做的事情是:通過document.cookie讀取了用戶身份驗證相關(guān)的 cookie樟凄,并將這些 cookie 發(fā)送到了攻擊者的服務器聘芜。攻擊者輕而易舉就拿到了用戶身份驗證信息,于是就可以搖搖大擺地冒充此用戶訪問你的服務器了(因為攻擊者有合法的用戶身份驗證信息缝龄,所以會通過你服務器的驗證)汰现。

如何設(shè)置 cookie?

知道了cookie的格式叔壤,cookie的屬性選項瞎饲,接下來我們就可以設(shè)置cookie了。首先得明確一點:cookie既可以由服務端來設(shè)置炼绘,也可以由客戶端來設(shè)置嗅战。

  1. 服務端設(shè)置 cookie
    不管你是請求一個資源文件(如 html/js/css/圖片),還是發(fā)送一個ajax請求,服務端都會返回response驮捍。而response header中有一項叫set-cookie疟呐,是服務端專門用來設(shè)置cookie的。如下圖所示东且,服務端返回的response header中有5個set-cookie字段启具,每個字段對應一個cookie(注意不能將多個cookie放在一個set-cookie字段中),set-cookie字段的值就是普通的字符串珊泳,每個cookie還設(shè)置了相關(guān)屬性選項鲁冯。

注意:
一個set-Cookie字段只能設(shè)置一個cookie,當你要想設(shè)置多個 cookie色查,需要添加同樣多的set-Cookie字段薯演。
服務端可以設(shè)置cookie 的所有選項:expires、domain综慎、path涣仿、secure、HttpOnly

  1. 客戶端設(shè)置 cookie
document.cookie = "name=Jonh; ";
document.cookie="age=12; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/";

注意:
客戶端可以設(shè)置cookie 的下列選項:expires示惊、domain好港、path、secure(有條件:只有在https協(xié)議的網(wǎng)頁中米罚,客戶端設(shè)置secure類型的 cookie 才能成功)钧汹,但無法設(shè)置HttpOnly選項。

用 js 如何設(shè)置多個 cookie

document.cookie = "name=Jonh";
document.cookie = "age=12";
document.cookie = "class=111";
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末录择,一起剝皮案震驚了整個濱河市拔莱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隘竭,老刑警劉巖塘秦,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異动看,居然都是意外死亡尊剔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門菱皆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來须误,“玉大人,你說我怎么就攤上這事仇轻【┝。” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵篷店,是天一觀的道長祭椰。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么方淤? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任侣监,我火速辦了婚禮,結(jié)果婚禮上臣淤,老公的妹妹穿的比我還像新娘橄霉。我一直安慰自己,他們只是感情好邑蒋,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布姓蜂。 她就那樣靜靜地躺著,像睡著了一般医吊。 火紅的嫁衣襯著肌膚如雪钱慢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天卿堂,我揣著相機與錄音束莫,去河邊找鬼。 笑死草描,一個胖子當著我的面吹牛览绿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播穗慕,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼饿敲,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了逛绵?” 一聲冷哼從身側(cè)響起怀各,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎术浪,沒想到半個月后瓢对,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡胰苏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年硕蛹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碟联。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡妓美,死狀恐怖僵腺,靈堂內(nèi)的尸體忽然破棺而出鲤孵,到底是詐尸還是另有隱情,我是刑警寧澤辰如,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布普监,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏凯正。R本人自食惡果不足惜毙玻,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望廊散。 院中可真熱鬧桑滩,春花似錦、人聲如沸允睹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缭受。三九已至胁澳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間米者,已是汗流浹背韭畸。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔓搞,地道東北人胰丁。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像喂分,于是被迫代替她去往敵國和親隘马。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

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