Cookie是什麼?我想任何一個網際網路的從業者都會很快的告訴你,它是一種瀏覽器本地儲存的一種方式.可以將一部分資源存放在本地,已達到更好的網路體驗.
然而隨著HTML5規範的普及,我們現在似乎有了更好的解決方案.LocalStorage
和SessionStorage
.它們是專門為本地儲存而誕生的解決方案.和Cookie相比起來.它們也似乎更加優秀:
- 它們有著更好用的API.
對於Cookie來說它只有一個document.cookie
這一個API可以使用,不管是讀取Cookie
還是儲存Cookie
你都只能使用它.並且Cookie
在儲存時只能儲存一段字串.所在讀取和儲存時你都要另外的區封裝方法已到達你想要的效果.
而LocalStorage
和SessionStorage
不一樣.以LocalStorage
為例,你儲存的時候有localStorage.setItem()
,你讀取的時候有localStorage.getItem()
,你想要刪除的時候有localStorage.removeItem()
.此外在儲存時,它們事以鍵值對的形式儲存的.所以更易於使用.
- 更大的儲存空間.
Cookie的儲存大小隻有4KB,而LocalStorage
和SessionStorage
是5MB.
- 永久的儲存時間.
Cookie的儲存是有過期時間的,到期自動刪除,而LocalStorage
是永久儲存,除非主動刪除.
經過上述的對比,我們發現,Cookie從任何方面來說都是完敗於LocalStorage
和SessionStorage
的,或許你會說它在相容性方面有著優勢.但是隨著HTML5標準的日益普及.這一點優勢也並沒有想象中的那麼重要.
那麼,既然如此我們是不是就要完全的拋棄Cookie,轉投LocalStorage
和SessionStorage
的懷抱了.其實並不是.在HTML5的時代,Cookie並不會落伍.依然會具有重要的地位.這是因為Cookie
的本地儲存功能雖然被代替了.但是他的本職工作卻依然無可替代.那它的本質工作是什麼了 ----伺服器遠端在瀏覽器端儲存資料並以此跟蹤和識別使用者的機制。
然我們來看看維基百科上對於Cookie的幾段描述:
Cookie(複數形態Cookies),中文名稱為“小型文字檔案”或“小甜餅”[1],指某些網站為了辨別使用者身份而儲存在使用者本地終端(Client Side)上的資料(通常經過加密)。定義於RFC2109。是網景公司的前僱員盧·蒙特利在1993年3月的發明[2]。
因為HTTP協議是無狀態的,即伺服器不知道使用者上一次做了什麼,這嚴重阻礙了互動式Web應用程式的實現。在典型的網上購物場景中,使用者瀏覽了幾個頁面,買了一盒餅乾和兩瓶飲料。最後結帳時,由於HTTP的無狀態性,不通過額外的手段,伺服器並不知道使用者到底買了什麼。 所以Cookie就是用來繞開HTTP的無狀態性的“額外手段”之一。伺服器可以設定或讀取Cookies中包含資訊,藉此維護使用者跟伺服器會話中的狀態。
在剛才的購物場景中,當使用者選購了第一項商品,伺服器在向使用者傳送網頁的同時,還傳送了一段Cookie,記錄著那項商品的資訊。當使用者訪問另一個頁面,瀏覽器會把Cookie傳送給伺服器,於是伺服器知道他之前選購了什麼。使用者繼續選購飲料,伺服器就在原來那段Cookie裡追加新的商品資訊。結帳時,伺服器讀取傳送來的Cookie就行了。
Cookie另一個典型的應用是當登入一個網站時,網站往往會請求使用者輸入使用者名稱和密碼,並且使用者可以勾選“下次自動登入”。如果勾選了,那麼下次訪問同一網站時,使用者會發現沒輸入使用者名稱和密碼就已經登入了。這正是因為前一次登入時,伺服器傳送了包含登入憑據(使用者名稱加密碼的某種加密形式)的Cookie到使用者的硬碟上。第二次登入時,(如果該Cookie尚未到期)瀏覽器會傳送該Cookie,伺服器驗證憑據,於是不必輸入使用者名稱和密碼就讓使用者登入了。
從上面維基百科上對Cookie
描述我們就可以看出,Cookie誕生的原因就是解決辨別使用者身份的問題.而本地儲存只是實現的一個手段而已.並不是它的主要目的.只是因為,在當時除了Cookie
之外並沒有一套有效的解決本地儲存的一個方案.所以Cookie
就被拿來借用.而借用的時間一長,許多人就以為Cookie
就是為了實現本地儲存的.反而將它的本職功能給忘記了.
那麼,獲取有人會問了,LocalStorage
和SessionStorage
既然代替了Cookie
的本地儲存功能,那麼是否能將Cookie
的驗證功能也一起代替了了.對此,我可以很絕對的告訴你這是不行的.因為服務端可以通過Cookie
來驗證使用者,因為瀏覽器在每次請求的時候都會帶上Cookie
中的資訊,這對於最多隻能儲存4KB大小的Cookie
來說.這是可以的.但對於有著5MB大小的LocalStorage
和SessionStorage
來說是不可想象的.此外,對於Cookie
服務端可以遠端給瀏覽器端設定,而LocalStorage
和SessionStorage
.所以,基於以上兩點,使用LocalStorage
和SessionStorage
完全代替Cookie
就目前而言是不可能的.
當然說了這麼多,Cookie
也並不是沒有缺陷.還是借用維基百科上面的資料:
Cookie的缺陷
- Cookie會被附加在每個HTTP請求中,所以無形中增加了流量。
- 由於在HTTP請求中的Cookie是明文傳遞的,所以安全性成問題。(除非用HTTPS)
- Cookie的大小限制在4KB左右。對於複雜的儲存需求來說是不夠用的。
反對Cookies者
一些人反對Cookies在網路中的應用,他們的理由如下:
- 識別不精確
- 識別有時候會發生錯誤
- 隱私,安全和廣告
Cookies在某種程度上說已經嚴重危及使用者的隱私和安全。其中的一種方法是:一些公司的高層人員為了某種目的(譬如市場調查)而訪問了從未去過的網站(通過搜尋引擎查到的),而這些網站包含了一種叫做網頁臭蟲的圖片,該圖片透明,且只有一個畫素大小(以便隱藏),它們的作用是將所有訪問過此頁面的計算機寫入Cookie。而後,電子商務網站將讀取這些Cookie資訊,並尋找寫入這些Cookie的網站,隨即傳送包含了針對這個網站的相關產品廣告的垃圾郵件給這些高階人員。
偷竊Cookies和指令碼攻擊
雖然Cookies沒有中電腦病毒那麼危險,但它仍包含了一些敏感訊息:使用者名稱,電腦名,使用的瀏覽器和曾經訪問的網站。使用者不希望這些內容洩漏出去,尤其是當其中還包含有私人資訊的時候。
這並非危言聳聽,跨站點指令碼(Cross site scripting)可以達到此目的。在受到跨站點指令碼攻擊時,Cookie盜賊和Cookie毒藥將竊取內容。一旦Cookie落入攻擊者手中,它將會重現其價值。
Cookie盜賊:蒐集使用者Cookie併發給攻擊者的黑客。攻擊者將利用Cookie訊息通過合法手段進入使用者帳戶。
Cookie投毒:一般認為,Cookie在儲存和傳回伺服器期間沒有被修改過,而攻擊者會在Cookie送回伺服器之前對其進行修改,達到自己的目的。例如,在一個購物網站的Cookie中包含了顧客應付的款項,攻擊者將該值改小,達到少付款的目的。這就是Cookie投毒。
Cookies的替代品
鑑於Cookie的侷限和反對者的聲音,有如下一些替代方法:
- Brownie方案,是一項開放原始碼工程,由SourceForge發起。Brownie曾被用以共享在不同域中的接入,而Cookies則被構想成單一域中的接入。這項方案已經停止開發。
- P3P,用以讓使用者獲得更多控制個人隱私權利的協議。在瀏覽網站時,它類似於Cookie。
- 在與伺服器傳輸資料時,通過在地址後面新增唯一查詢串,讓伺服器識別是否合法使用者,也可以避免使用Cookie。