轉載:原文地址瀏覽器
早期Web開發面臨的最大問題之一是如何管理狀態。服務器端沒有辦法知道兩個請求是否來自於同一個瀏覽器。那時的辦法是在請求的頁面中插入一個token,而且在下一次請求中將這個token返回(至服務器)。這就須要在form中插入一個包含token的隱藏表單域,或着在URL的qurey字符串中傳遞該token。這兩種辦法都強調手工操做而且極易出錯。
cookies工做原理的基本信息在RFC2109中被規範化
cookie是什麼?
一個cookie就是存儲在用戶主機瀏覽器中的一小段文本文件。
Cookies是純文本形式,它們不包含任何可執行代碼。
一個Web頁面或服務器告之瀏覽器來將這些信息存儲而且基於一系列規則在以後的每一個請求中都將該信息返回至服務器。Web服務器以後能夠利用這些信息來標識用戶。
經過HTTP的Set-Cookie消息頭,Web服務器能夠指定存儲一個cookie。
Set-Cookie消息的格式以下面的字符串(中括號中的部分都是可選的)
Set-Cookie:value [ ;expires=date][ ;domain=domain][ ;path=path][ ;secure]
value部分,一般是一個name=value格式的字符串。事實上有不少瀏覽器用本身的格式,有細微的不一樣。
當一個cookie存在,而且可選條件容許的話,該cookie的值會在接下來的每一個請求中被髮送至服務器。
cookie的值被存儲在名爲Cookie的HTTP消息頭中,而且只包含了cookie的值,其它的選項所有被去除。
可選項只是存在於瀏覽器端,並不須要發給服務端。
例如: Cookie : value
若是在指定的請求中有多個cookies,那麼它們會被分號和空格分開,例如:
Cookie:value1 ; value2 ; name1=value1
有效期選項(The expires option)
指定了cookie過時的時間,過時後可能會被瀏覽器刪掉。
格式爲Wdy,DD-Mon--YYYY HH:MM:SS GMT,例如:
Set-Cookie:name=Nicholas;expires=Sat, 02 May 2009 23:38:25 GMT
在沒有expires選項時,cookie的壽命僅限於單一的會話中。瀏覽器的關閉意味這一次會話的結束,因此會話cookie只存在於瀏覽器保持打開的狀態之下。
domain選項(The domain option)
指示cookie將要發送到哪一個域或那些域中。默認狀況下,domain會被設置爲建立該cookie的頁面所在的域名。
domain選項被用來擴展cookie值所要發送域的數量。例如:
Set-Cookie:name=Nicholas;domain=www.baidu.com
不少時候大網站存在二級域名,例如fanyi.baidu.com。cookies可能只發給對應的二級域名。
Path選項(The path option)
在請求相匹配的路徑的時候,纔會發送cookie
例如:
Set-Cookie:name=Nicholas;path=/blog
在這個例子中,path選項值會與/blog,/blogrool等等相匹配;任何以/blog開頭的選項都是合法的。
secure選項(The secure option)
該選項只是一個標記而且沒有其它的值。只有當請求是經過SSL和HTTPS建立時,纔會發送。
這種cookie的內容意指具備很高的價值而且可能潛在的被破解以純文本形式傳輸。例如
Set-Cookie:name=Nicholas;secure
現實中,機密且敏感的信息毫不應該在cookies中存儲或傳輸,由於cookies的整個機制都是本來不安全的。
默認狀況下,在HTTPS連接上傳輸的cookies都會被自動添加上secure選項。
cookie的維護和生命週期(cookie maintenance and lifecycle)
任意數量的選項均可以在單一的cookie中指定,而且這些選項能夠以任何順序存在,例如
Set-Cookie:name=Nicholas; domain=nczonline.net; path=/blog
這個cooke有四個標識符:cookie的name,domain,path,secure標記。
要想在未來改變這個cookie的值,須要發送另外一個具備相同cookie name,domain,path的Set-Cookie消息頭。
例如:
Set-Cooke:name=Greg; domain=nczonline.net; path=/blog
這將以一個新的值來覆蓋原來cookie的值。
然而,僅僅只是改變這些選項的某一個也會建立一個徹底不一樣的cookie,
例如:
Set-Cookie:name=Nicholas; domain=nczonline.net; path=/
在返回這個消息頭後,會存在兩個同時擁有「name」的不一樣的cookie。
若是你訪問在www.nczonline.NET/blog下的一個頁面,如下的消息頭將被包含進來:
Cookie:name=Greg;name=Nicholas
在這個消息頭中存在了兩個名爲「name」的cookie,path值越詳細則cookie越靠前。domain-path越詳細則cookie字符串越靠前。假設我在ww.nczonline.Net/blog下而且發送了另外一個cookie,其設置以下:
Set-Cookie:name=Mike
那麼返回的消息頭如今則變爲:
Cookie:name=Mike;name=Greg;name=Nicholas
因爲包含「Mike」的cookie使用了域名(www.nczonline.net)做爲其domain值而且以全路徑(/blog)做爲其path值,則它較其它兩個cookie更加詳細。
使用失效日期(using expiration dates)
當cookie建立時包含了失效日期,這個失效日期則關聯了以name-domain-path-secure爲標識的cookie。
要改變一個cookie的失效日期,必須指定一樣的組合。當改變一個cookie的值時,你沒必要每次都設置失效日期,由於它不是cookie標識信息的組成部分。
例如:
Set-Cookie:name=Mike;expires=Sat,03 May 2025 17:44:22 GMT
如今已經設置了cookie的失效日期,因此下次我想要改變cookie的值時,我只須要使用它的名字:
Set-Cookie:name=Matt
在cookie上的失效日期並無改變,由於cookie的標識符是相同的。實際上,只有你手工的改變cookie的失效日期,不然其失效日期不會改變。這意味着在同一個會話中,一個會話cookie能夠變成一個持久化cookie(一個能夠在多個會話中存在的),反之則不可。爲了要將一個持久化cookie變爲一個會話cookie,你必須刪除這個持久化cookie,這隻要設置它的失效日期爲過去某個時間以後再建立一個同名的會話cookie就能夠實現。
須要記得的是失效日期是以瀏覽器運行的電腦上的系統時間爲基準進行覈實的。沒有任何辦法來來驗證這個系統時間是否和服務器的時間同步,因此當服務器時間和瀏覽器所處系統時間存在差別時這樣的設置會出現錯誤。
cookie自動刪除(automatic cookie removal)
cookie會被瀏覽器自動刪除,一般存在如下幾種緣由:
會話cooke(Session cookie)在會話結束時(瀏覽器關閉)會被刪除
持久化cookie(Persistent cookie)在到達失效日期時會被刪除
若是瀏覽器中的cookie限制到達,那麼cookies會被刪除覺得新建cookies建立空間。
對於任何這些自動刪除來講,Cookie管理顯得十分重要,由於這些刪除都是無心識的。
Cookie限制條件(Cookie restrictions)
在cookies上存在了諸多限制條件,來阻止cookie濫用並保護瀏覽器和服務器免受一些負面影響。
有兩種cookies的限制條件:cookies的屬性和cookies的總大小。
原始的規範中限定每一個域名下不超過20個cookies,早期的瀏覽器都遵循該規範,而且在IE7中有個更近一步的提高。
在微軟的一次更新中,他們在IE7中增長cookies的限制到50個,與此同時Opera限定cookies個數爲30.Safari和Chrome對與每一個域名下的cookies個數沒有限制。
發向服務器的全部cookies的最大數量(空間)仍舊維持原始規範中所指出的:4KB。
全部超出該限制的cookies都會被截掉而且不會發送至服務器。
Subcookies
鑑於cookie的數量限制,開發者提出的subcookies的觀點來增長cookies的存儲量。
Subcookies是一些存儲在一個cookie的value中的一些name-value對,而且一般與如下格式相似:
name=a=b&c=d&e=f&g=h
這種方式容許在單個cookie中保存多個name-value對,而不會超過瀏覽器cookie的數量限制。
經過這種方式建立cookies的負面影響是,須要自定義解析方式來提取這些值,相比較而言cookies的格式會更爲簡單。服務器端框架已開始支持subcookies的存儲。安全