經常使用的本地存儲——cookie篇

1、引言

隨着瀏覽器的處理能力不斷加強,愈來愈多的網站開始考慮將數據存儲在「客戶端」,那就不得不談談本地存儲了。本地存儲的好處顯而易見,一是避免取回數據前頁面一片空白,若是不須要最新數據也能夠減小向服務端請求的次數,從而減小用戶等待從服務器獲取數據的時間,二是網絡狀態不佳時仍能夠顯示離線數據html

下面來看看經常使用的本地存儲。web

chrome瀏覽器打開一個網頁,進入開發者模式,點擊Resources,咱們能夠看到:chrome

clipboard.png

以上的 indexedDBLocal StorageSession StorageCookies,就是經常使用的本地存儲其中幾種。下面咱們一一瞭解。數據庫

2、經常使用的本地存儲

一、cookie瀏覽器

HTTP cookie,一般直接叫作cookie,是客戶端用來存儲數據的一種選項,它既能夠在客戶端設置也能夠在服務器端設置。cookie會跟隨任意HTTP請求一塊兒發送。安全

優勢:兼容性好服務器

缺點:一是增長了網絡流量;二則是它的數據容量有限,最多隻能存儲4KB的數據,瀏覽器之間各有不一樣;三是不安全。 cookie

二、userData網絡

userData是微軟經過一個自定義行爲引入的持久化用戶數據的概念。用戶數據容許每一個文檔最多128KB數據,每一個域名最多1MB數據。session

缺點:userData不是 web 標準的一部分,只有IE支持

三、web存儲機制

web storage,包括兩種:sessionStoragelocalStorage,前者嚴格用於一個瀏覽器會話中存儲數據,由於數據在瀏覽器關閉後會當即刪除;後者則用於跨會話持久化地存儲數據。

缺點:IE不支持 SessionStorage,低版本IE ( IE6, IE7 ) 不支持 LocalStorage,而且不支持查詢語言

四、indexedDB

indexed Database API,簡稱爲indexedDB,是在瀏覽器中保存結構化數據的一種「數據庫」。它相似SQL數據庫的結構化數據存儲機制,代替了廢棄已久的web SQL Database API,它可以在客戶端存儲大量的結構化數據,而且使用索引高效檢索的API。

缺點:兼容性很差,未獲得大部分瀏覽器的支持。

五、Flash cookie

Flash本地存儲,相似於HTTP cookie,它是利用 SharedObject類來實現本地存儲信息。它默認容許每一個站點存儲不超過100K的數據,遠大於cookie,並且可以跨瀏覽器。

缺點:瀏覽器需安裝 Flash 控件,畢竟它是經過Flash的類來存儲。所幸的是,沒有安裝Flash的用戶極少。

六、Google Gears

Google Gears是Google在07年發佈的一個開源瀏覽器插件,Gears 內置了一個基於SQLite的嵌入式 SQL數據庫,並提供了統一API 對 數據庫進行訪問,在取得用戶受權以後,每一個站點能夠在SQL數據庫中存儲「不限大小」的數據。

缺點:須要安裝 Google Gears 組件

下面將對 cookie 進行詳細的介紹。

3、cookie的用途

3.1 概述

下面來詳細談談cookie。

Cookie是一小段文本信息,伴隨着用戶請求在 Web 服務器和瀏覽器之間傳遞。它存儲於訪問者的計算機中,每當同一臺計算機經過瀏覽器請求某個頁面時,就會發送這個 cookie。

首先聲明,它是「瀏覽器」提供的一種機制,它將 document 對象的 cookie 屬性提供給 JavaScript。可使用JavaScript來建立和取回 cookie 的值,所以咱們能夠經過document.cookie訪問它。

cookie是存於用戶硬盤的一個文件,這個文件一般對應於一個域名,也就是說,cookie能夠跨越一個域名下的多個網頁,但不能跨越多個域名使用。

3.2 cookie的用途及工做原理

那cookie具體能幹什麼呢?

cookie 將信息存儲於用戶硬盤,所以能夠做爲全局變量,這是它最大的一個優勢。它最根本的用途是 Cookie 可以幫助 Web 站點保存有關訪問者的信息,如下列舉cookie的幾種小用途。

  • 保存用戶登陸信息。這應該是最經常使用的了。當您訪問一個須要登陸的界面,例如微博、百度及一些論壇,在登陸事後通常都會有相似"下次自動登陸"的選項,勾選事後下次就不須要重複驗證。這種就能夠經過cookie保存用戶的id。
  • 建立購物車。購物網站一般把已選物品保存在cookie中,這樣能夠實現不一樣頁面之間數據的同步(同一個域名下是能夠共享cookie的),同時在提交訂單的時候又會把這些cookie傳到後臺。
  • 跟蹤用戶行爲。例如百度聯盟會經過cookie記錄用戶的偏好信息,而後向用戶推薦個性化推廣信息,因此瀏覽其餘網頁的時候常常會發現旁邊的小廣告都是本身最近百度搜過的東西。這是能夠禁用的,這也是cookie的缺點之一。

那麼,cookie是怎麼起做用的呢?

在上一節中咱們知道 cookie 是存在用戶硬盤中,用戶每次訪問站點時,Web應用程序均可以讀取 Cookie 包含的信息。當用戶再次訪問這個站點時,瀏覽器就會在本地硬盤上查找與該 URL 相關聯的 Cookie。若是該 Cookie 存在,瀏覽器就將它添加到request headerCookie字段中,與http請求一塊兒發送到該站點。

clipboard.png

要注意的是,添加到 request header 中是「瀏覽器的行爲」,存儲在cookie的數據「每次」都會被瀏覽器「自動」放在http請求中。所以,若是這些數據不是每次都要發給服務器的話,這樣作無疑會增長網絡流量,這也是cookie的缺點之一。爲了不這點,咱們必須考慮什麼樣的數據才應該放在cookie中,而不是濫用cookie。每次請求都須要攜帶的信息,最典型的就是身份驗證了,其餘的大多信息都不適合放在cookie中。

4、cookie的格式

明白了工做原理後,接着咱們來看看cookie長什麼樣,而後再一步步深刻了解該怎麼去用它。

那麼,如何獲取 cookie 呢?從第1小節瞭解到,瀏覽器提供了 cookie 屬性給 JavaScript,所以能夠經過 document.cookie 來訪問這個頁面中的cookie。

clipboard.png

這是一串字符串,仔細觀察,咱們能夠發現規律。每一個 cookie 都以名/值對的形式,即 name=value,名稱和值都必須是URL編碼的,且兩對cookie間以分號和空格隔開。(ps:千萬不要忘了空格,特別是在獲取某個 cookie 時)

依舊是進入開發者模式,咱們來看下Resources下的Cookies

clipboard.png

紅色標註的那行,稍微猜測一下,也能夠知道它是與cookie相關的值和屬性。name、value 沒必要多說,天然是 cookie 的名和值。domainPathExpries/Max-agehttponly(即HTTP選項)、Secure 等均是 cookie 的屬性,咱們一一瞭解下。

咱們先手動添加幾個cookie,而後再來一一看下屬性(具體設置cookie的方法在下一小節詳解)。

代碼以下:

document.cookie = "test1=myCookie1;"
document.cookie = "test2=myCookie2; domain=.google.com.hk; path=/webhp"
document.cookie = "test3=myCookie3; domain=.google.com.hk; expires=Sat, 04 Nov 2017 16:00:00 GMT; secure"
document.cookie = "test4=myCookie4; domain=.google.com.hk; max-age=10800;"

clipboard.png

4.1 domain和path

domain 和 path 這兩個選項共同決定了cookie能被哪些頁面共享。

clipboard.png

標紅區域是默認狀況,正如例1中未設置domain和path最終顯示的狀況。

domain 參數是用來控制 cookie對「哪一個域」有效,默認爲設置 cookie的那個域。這個值能夠包含子域,也能夠不包含它。如上圖的例子,Domain選項中,能夠是".google.com.hk"(不包含子域,表示它對google.com.hk的全部子域都有效),也能夠是"www.google.com.hk"(包含子域)。

path用來控制cookie發送的指定域的「路徑」,默認爲"/",表示指定域下的全部路徑都能訪問。它是在域名的基礎下,指定能夠訪問的路徑。例如cookie設置爲"domain=.google.com.hk; path=/webhp",那麼只有".google.com.hk/webhp"及"/webhp"下的任一子目錄如"/webhp/aaa"或"/webhp/bbb"會發送cookie信息,而".google.com.hk"就不會發送,即便它們來自同一個域。

4.2 expries/max-age失效時間

expries 和 max-age 是用來決定cookie的生命週期的,也就是cookie什麼時候會被刪除。

clipboard.png

標紅區域爲默認狀況,即Session,表示瀏覽器會話結束時(即關閉瀏覽器)就會刪除cookie。

固然,用戶也能夠經過expries設置刪除時間。這個值是個GMT格式的日期,相似例三中的Sat, 04 Nov 2017 16:00:00 GMT,這代表這個 cookie 將在2017-11-04的16時整失效,在此期間瀏覽器關閉後此cookie仍會保存在用戶的機器中。GMT格式能夠經過 toGMTString()toUTCString() 得到。若是設置的失效時間是個之前的時間,則 cookie 會被當即刪除,這也是用來刪除 cookie 的方法。

在新的http協議中已經使用 max-age 屬性來取代 expries。expries 表示的是失效時間,準確講是「時刻」,max-age表示的是生效的「時間段」,以「秒」爲單位。若 max-age 爲正值,則表示 cookie 會在 max-age 秒後失效。如例四中設置"max-age=10800;",也就是生效時間是3個小時,那麼 cookie 將在三小時後失效。若 max-age 爲負值,則cookie將在瀏覽器會話結束後失效,即 session,max-age的默認值爲-1。若 max-age 爲0,則表示刪除cookie。

4.3 secure

secure是 cookie 的安全標誌,經過cookie直接包含一個secure單詞來指定,也是cookie中惟一一個非名值對兒的部分。指定後,cookie只有在使用SSL鏈接(如HTTPS請求)時纔會發送到服務器。

默認狀況爲空,不指定 secure 選項,即不管是 http 請求仍是 https 請求,均會發送cookie。

clipboard.png

標紅區域爲指定 secure 後的狀況,同時也說明指定 secure 後 cookie 仍可見。

注意:只有保證網頁是https協議(或其餘安全協議)請求的,才能客戶端在客戶端經過 js 去設置secure 類型的 cookie。

4.4 httponly

httponly屬性是用來限制客戶端腳本對cookie的訪問。將 cookie 設置成 httponly 能夠減輕xss攻擊的危害,防止cookie被竊取,以加強cookie的安全性。(因爲cookie中可能存放身份驗證信息,放在cookie中容易泄露)

HTTP那列用來表示是否設置了httponly屬性,若設置了httponly,則會打勾(即標紅區域)

clipboard.png

clipboard.png

咱們用 js 獲取下cookie,能夠發現訪問不到 NID 這個cookie,說明js是沒法讀取和修改 httponly cookies,固然也不能設置 cookie 爲 httponly,這隻能經過服務器端去設置。

默認狀況是不指定 httponly,便可以經過 js 去訪問。

5、設置cookie

將 cookie 的屬性介紹後,下一步就該談談如何利用這些屬性去設置 cookie 了~

5.1 服務器端設置

服務器經過發送一個名爲 Set-Cookie 的HTTP頭來建立一個cookie,做爲 Response Headers 的一部分。以下圖所示,每一個Set-Cookie 表示一個 cookie(若是有多個cookie,需寫多個Set-Cookie),每一個屬性也是以名/值對的形式(除了secure),屬性間以分號加空格隔開。格式以下:

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

只有cookie的名字和值是必需的。

clipboard.png

注意,經過 Set-Cookie 指定的可選項(域、路徑、失效時間、secure標誌)只會在「瀏覽器端」使用,它們都是服務器給瀏覽器的指示,以指定什麼時候應該發送cookie。這些參數不會被髮送至服務器端,只有name和value纔會被髮送。

5.2 客戶端設置

客戶端設置cookie的格式和Set-Cookie頭中使用的格式同樣。以下:

document.cookie = "name=value[; expires=GMTDate][; domain=domain][; path=path][; secure]"

能夠參照第3小節的四個例子測試下。

document.cookie = "test1=myCookie1;"
document.cookie = "test2=myCookie2; domain=.google.com.hk; path=/webhp"
document.cookie = "test3=myCookie3; domain=.google.com.hk; expires=Sat, 04 Nov 2017 16:00:00 GMT; secure"
document.cookie = "test4=myCookie4; domain=.google.com.hk; max-age=10800;"

若想要添加多個cookie,只能重複執行 document.cookie(如上)。這可能和平時寫的 js 不太同樣,通常重複賦值是會覆蓋的,但對於cookie,重複執行 document.cookie 並「不覆蓋」,而是「添加」(針對「不一樣名」的)。

5.3 cookie的修改

上一節的最後是否有些疑惑?針對不一樣名的cookie,執行document.cookie是添加,那「同名」的呢?實地演練一下~

以下圖,咱們以test1做爲實例試驗下。

clipboard.png

再執行次 document.cookie = "test1=newCookie;"

clipboard.png

咱們發現,原來值爲myCookie1的cookie不見了,test1原來的值myCookie1newCookie覆蓋了,這也是這章要講解的,修改cookie的方法。還沒結束哦,咱們再試下能不能修改參數。

document.cookie = "test1=newCookie; max-age=3600; secure"

clipboard.png

如上圖,咱們成功更改了名爲test1的cookie的過時時間及安全標誌。

document.cookie = "test1=newCookie; domain=.google.com.hk; max-age=3600; secure"
document.cookie = "test1=newCookie; path=/webhp; max-age=3600; secure"

clipboard.png

咱們發現沒有覆蓋原來的cookie,而是新增了cookie。這也是修改cookie時須要注意的地方,能夠修改原cookie的expries、secure屬性,但不能修改domain、path屬性。修改cookie時domain、path必須與原cookie保持一致。

5.4 cookie的刪除

cookie的刪除其實特別簡單,也是對此cookie從新賦值,上面介紹expriesmax-age時也有提到,將expries設爲一個過去的時間或將max-age設爲0,均可以刪除cookie。同時也要特別注意此cookie的domain、path要與原來保持一致。

6、cookie編碼

若 cookie 的名或值中包含分號、逗號和空格這三個特殊字符,那麼它須要通過URL編碼。通常可使用encodeURIComponent進行編碼,它對應的解碼函數是decodeURIComponent。若要給 cookie 指定額外的信息,只要將參數追加到該字符串(以下例)。

document.cookie = encodeURIComponent("test") + "=" + encodeURIComponent("myCookie") + "; max-age=3600";

7、cookie的缺點

  • 安全性:因爲cookie在HTTP中是明文傳遞的,其中包含的數據均可以被他人訪問,可能會被篡改、盜用。
  • 大小限制:cookie的大小限制在4KB左右,若要作大量存儲顯然不是理想的選擇。
  • 增長流量:cookie每次請求都會被自動添加到Request Header中,無形中增長了流量。cookie信息越大,對服務器請求的時間也越長。

所以要慎用cookie,不要在cookie中存儲重要和敏感的數據。

8、結語

關於 cookie 的部分就先聊到這啦~有不對的地方歡迎指正~

參考資料:

相關文章
相關標籤/搜索