Cookie 沒你不行

Cookie 沒你不行

前言:

你知道嗎,當有人悄悄的禁用了你瀏覽器的cookie,一場災難將會發生,若是你不是一個開發人員,那更是災難。 
筆者在寫這篇文章前作了下實驗,BAT所有登陸不了,只有baidu給了我的性化的提示:Alt text 
既然cookie如此重要,你真的對它瞭解嗎?javascript

起源

講這個仍是得先講講cookie是如何誕生的,由於HTTP協議是無狀態的,即服務器不知道用戶上一次作了什麼,這嚴重阻礙了交互式Web應用程序的實現。因而有這麼一我的,網景公司的前僱員盧·蒙特利在1993年3月的發明了cookie。最初在1997年2月定義於 RFC 2109,後來有兩次更新,於2000年10月的RFC2965和2011年4月RFC6265。 
你能夠發現這幾個文檔的標題都是: HTTP State Management Mechanism (http 狀態管理機制) 。 
講到這裏,有沒有以爲cookie 是一個神奇的存在, 1993年發明的,一直用到如今 ,雖然互聯網技術突飛猛進,但它仍是保留下來,而且不可或缺,rfc文檔 也有兩次更新 。css

究竟是什麼?

Cookie 是服務器保存在瀏覽器的一小段文本信息。這是個純文本的信息,而且按照協議規定的格式來存儲 。瀏覽器每次向服務器發出請求,就會自動附上這段信息,因而Web 服務器就可使用這些信息來識別不一樣的用戶 。生活中咱們使用的大部分須要登陸的網站,登陸成功後都會設置一個cookie到瀏覽器,只要這個cookie 存在,用戶就能夠瀏覽網站的任意頁面,手動清理掉這個cookie,就至關於退出登陸。 這也就是爲何前言中會出現:若是禁用瀏覽器cookie功能,大部分網站就沒法登陸,沒法使用須要登陸後才能使用的功能了。html

使用場景

會話(session)管理:保存登陸、購物車等須要記錄的信息。 
個性化:保存用戶的偏好,好比網頁的字體大小、背景色、地域等等。 
追蹤:記錄和分析用戶行爲,廣告。java

這裏有必要提一下,瀏覽器對單個cookie的大小,一個網站的cookie個數,總的大小和個數都有限制,其實cookie不適合用來做爲大量數據的客戶端存儲,如過須要這個功能,可使用瀏覽器的Local Storage 、IndexDB等新的功能來替代,這裏就不作延展。jquery

cookie的缺陷 
Cookie會被附加在每一個HTTP請求中,因此無形中增長了流量。 
因爲在HTTP請求中的Cookie是明文傳遞的,因此安全性成問題,除非用HTTPS。 
Cookie的大小限制在4KB左右,數量在20左右,對於複雜的存儲需求來講是不夠用的。程序員

如何使用cookie

Cookie其實是由瀏覽器在管理(瀏覽器放出接口),這個問題就變成如何指揮瀏覽器增刪改查cookie ,咱們知道瀏覽器是遵照http協議的,還有另外一方web服務端也是遵照的。咱們能夠經過這個來指揮瀏覽器操做cookie。web

服務端要操做cookie是經過響應頭:Set-Cookie , 瀏覽器接受到這個響應頭 ,就至關於收到命令去操做cookie ,具體是添加cookie ,刪除cookie 仍是修改cookie 要看後面的值 ,一個Set-Cookie 響應頭自能操做一個cookie ,一個響應能夠有多個Set-Cookie響應頭 ,這樣一次響應就能操做多個cookie, 
響應頭中的cookie實例: 
Set-Cookie:ykjjdc=c89e252fb3ce3cf203f; domain=.jjw.com; expires=Mon, 21-Mar-2118 07:00:11 GMT; path=/ 
用 「;」 分隔的字符串,每一段基本是一個鍵值對。 
服務端要獲取cookie 是經過 請求頭: Cookie ,http協議規定瀏覽器每次發起一個請求,要篩選符合要求的cookie(好比域相同,路徑相同,沒過時等)放在請求頭Cookie中 傳遞給服務端 。 
請求頭中的Cookie實例: 
Cookie: cna=UfdnD69NHXgE8g; UM_distinctid=16223df34200 
能夠到也是用 「;」 分隔的字符串, 沒一段就是一個cookie ,忽略了cookie的其餘屬性,也就是說服務端不知道這個cookie是誰寫的,何時將會過時。chrome

document.cookie 是客戶端讀寫cookie的惟一接口 ,這個屬性可讀可寫 。 
讀的狀況下,返回當前腳本路徑下全部的cookie(不包含屬性包好httponly的),按照相關性排序(解決不一樣路徑下相同名字cookie的問題)。讀出來的示例: 
iddc=fsfea; fsf=3; yssskjjdc=ssfe; ykjjdc=fsa瀏覽器

寫的狀況下,一次只能寫一個cookie,不會覆蓋已有cookie ,根據你寫的內容,會出現 添加一個cookie ,修改一個cookie ,刪除一個cookie等不一樣的結果 。 
寫的示例以下:安全

document.cookie = "foo=bar; expires=Fri, 31 Dec 2020 23:59:59 GMT";

能夠看出都是對字符串的處理,這種處理容易出錯,目前比較流行的cookie幫助類有 jquery.cookie.js 和yui中的對cookie的相關函數。能夠方便的讀寫cookie。

不一樣服務端代碼中對cookie封裝的原理就是 基於 http協議中的cookie機制 ,上文中有提到,asp.net 也不例外。 
asp.net 中有一個類 System.Web.HttpCookie 來對應cookie ,咱們來看看他的結構

HttpCookie 屬性 cookie 原生屬性 描述
Domain domain 獲取或設置要將與 cookie 相關聯的域。
Expires expires 獲取或設置的過時日期和時間的 cookie。
HasKeys 獲取一個值,該值指示 cookie 是否有子項。subcookies應用
HttpOnly httponly 獲取或設置一個值,指定 cookie 是由客戶端腳本訪問。
Name name 獲取或設置 cookie 的名稱。
Path path 獲取或設置要與當前 cookie 傳輸的虛擬路徑。
Secure secure 獲取或設置一個值,該值指示是否傳輸,即經過 HTTPS 僅使用安全套接字層 (SSL)-的 cookie。
Value value 獲取或設置一個單獨的 cookie 值。
Values 獲取包含在一個 cookie 對象內的鍵/值對的集合。subcookies,解決cookie個數過多問題
max-age 對 expires屬性的補充 ,存在瀏覽器兼容性問題
host-only 強制域徹底一致纔可訪問

經過上表咱們能夠看到 ,原生cookie的屬性基本和aspnet 中的一致。 
咱們能夠經過Request.Cookies 獲得請求頭中的cookie ,而且能夠很方便的拿到對應的值 , 
(有興趣的朋友能夠研究下 ,有相同的cookie名時服務端的取值狀況 )。

在aspnet 中服務端能夠經過下面的對象或者語法方便的操做cookie 。

Response.AppendCookie()
Response.AppendHeader("Set-Cookie" ,"iron=fage");
Response.SetCookie()
Response.Cookie.Add()

可是筆者認爲這個設計還不如 JavaScript中 cookie 的操做設計,一個屬性增刪改查全是它 。 
這樣的封裝設計干擾了程序員對cookie的學習瞭解。

web.config 關於cookie的全局配置節點 , 你能夠指定cookie的域 ,固然這個域必須和地址欄中的主域一致; 也能夠爲了安全起見配置httpOnlyCookies 使默認輸出的cookie 都是js不能讀取操做的 ; 還能夠配置 requireSSL 是瀏覽器只有在https地址上發送這個cookie (這個的前提也是當前協議是用的https)。

<httpCookies domain="String"
httpOnlyCookies="true|false"
requireSSL="true|false" />

工做中,除了瀏覽器發起http請求外, 還有一種狀況是本身編寫代碼來發起http請求,好比對第三方http接口的請求。

CookieContainer cookieContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.CookieContainer = cookieContainer; //這個屬性用來傳遞cookie
 
using( WebResponse response = request.GetResponse() ) {
using( StreamReader reader = new StreamReader(response.GetResponseStream(), encoding) ) {
return reader.ReadToEnd();
}
}
//執行上面的代碼後,若是http響應中有cookie,將會追加到 cookieContainer ;

Cookie最核心的應用應該就是做爲會話機制了,正如前言中提到的,瀏覽器停掉cookie ,大部分網站都沒法登陸的數據。 其實 asp.net 中的 Session[「」] 默認配置下,就依賴於cookie ,會在客戶端用cookie存儲一個sessionid 。

Cookie最多見的應用還有 ,記錄用戶的使用偏好 ,好比用戶 經常使用城市, 語言 ,網站主題,字體等 , 固然這些均可以存儲服務端和用戶信息關聯 ,可是若是網站不須要登陸,這些數據存儲在服務端就不合適了。

還有嗎?

工具

瀏覽器自己就會提供cookie 的開關配置,用戶能夠根據本身須要來開啓或者關閉,或者開啓部分網站,關閉部分網站等設置 。 
瀏覽器也會提供cookie的管理工具 , 可是大都不是很好用 。 chrome 內核瀏覽器 的開發人員工具能夠很方便的查看cookie 可是管理就不是很便利了 。 
瀏覽器插件是解決這個問題的終極方案, EditThisCookie 這款瀏覽器插件是個不錯的選擇。

Q&A

  • 若是你須要寫一個瀏覽器,你須要對cookie 作哪些處理
  • 接口化開發,對於接口的響應中的cookie如何處理 。
  • 除了經過 set-Cookie ,JavaScript 操做cookie ,還有其餘方式嗎
  • 向圖片,css ,js 發出的請求 會攜帶cookie 嗎
  • 說說cookie 的缺點
  • 對咱們工做的啓發 ?

Thanks

資料

相關文章
相關標籤/搜索