深入理解瀏覽器存儲(chǔ)

前言

隨著Web應(yīng)用程序出現(xiàn)以來,人們對(duì)與能夠直接在客戶端上存儲(chǔ)信息能力的要求始終沒有停止過。應(yīng)用開發(fā)人員在找各種方式將數(shù)據(jù)存儲(chǔ)在客戶端上。從剛開始的Cookie存儲(chǔ)方案,到現(xiàn)在的Web Storage和indexedDB,本文將主要介紹這三種瀏覽器存儲(chǔ)方式優(yōu)缺點(diǎn)。

Cookie

1、Cookie是什么?

HTTP Cookie,通常直接叫做cookie,起初是在客戶端用于存儲(chǔ)會(huì)話信息的。該標(biāo)準(zhǔn)要求服務(wù)器對(duì) 任意 HTTP請(qǐng)求發(fā)送 Set-CookieHTTP頭作為響應(yīng)的一部分,其中包含會(huì)話信息。例如,這種服務(wù)器響 應(yīng)的頭可能如下:

HTTP/1.1 200 OK 
Content-type: text/html 
Set-Cookie: name=value 
Other-header: other-header-value 

這個(gè)HTTP響應(yīng)設(shè)置以name為名稱、以value為值的一個(gè)cookie,名稱和值在傳送時(shí)都必須是 URL 編碼的。瀏覽器會(huì)存儲(chǔ)這樣的會(huì)話信息,并在這之后,通過為每個(gè)請(qǐng)求添加 Cookie ,HTTP 頭將信 息發(fā)送回服務(wù)器,如下所示:

GET /index.html HTTP/1.1 
Cookie: name=value 
Other-header: other-header-value 

發(fā)送回服務(wù)器的額外信息可以用于唯一驗(yàn)證客戶來自于發(fā)送的哪個(gè)請(qǐng)求。

2、Cookie主要構(gòu)成:

  • name(名稱):一個(gè)唯一確定cookie的名稱。cookie的名稱必須是經(jīng)過 URL編碼的。
  • value(值):儲(chǔ)存在 cookie中的字符串值。值必須被 URL編碼。
  • Domain(域):cookie 對(duì)于哪個(gè)域是有效的。所有向該域發(fā)送的請(qǐng)求中都會(huì)包含這個(gè) cookie 信息。
  • path(路徑):對(duì)于指定域中的那個(gè)路徑,應(yīng)該向服務(wù)器發(fā)送 cookie
  • Expires/Max-Age(失效時(shí)間):表示 cookie 何時(shí)應(yīng)該被刪除的時(shí)間戳(也就是,何時(shí)應(yīng)該停止向服務(wù)器發(fā)送這個(gè) cookie)。
  • HttpOnly:這個(gè)屬性是面試的時(shí)候??嫉?,如果這個(gè)屬性設(shè)置為true,就不能通過js腳本來獲取cookie的值,能有效的防止xss攻擊。
  • Secure(安全標(biāo)志):指定后,cookie 只有在使用 SSL 連接的時(shí)候才發(fā)送到服務(wù)器。
image

3、Cookie的原理

image

第一次訪問網(wǎng)站的時(shí)候,瀏覽器發(fā)出請(qǐng)求,服務(wù)器響應(yīng)請(qǐng)求后,會(huì)在響應(yīng)頭里面添加一個(gè)Set-Cookie,將cookie放入到響應(yīng)請(qǐng)求中,在瀏覽器第二次發(fā)請(qǐng)求的時(shí)候,會(huì)通過Cookie請(qǐng)求頭部將Cookie信息發(fā)送給服務(wù)器,服務(wù)端會(huì)辨別用戶身份,另外,Cookie的過期時(shí)間、域、路徑、有效期、適用站點(diǎn)都可以根據(jù)需要來指定。

4、Cookie生成方式

Cookie的生成方式主要有兩種:

  1. 服務(wù)端設(shè)置 cookie

客戶端第一次向服務(wù)端請(qǐng)求時(shí),在相應(yīng)的請(qǐng)求頭中就有set-cookie字段,用來標(biāo)識(shí)是哪個(gè)用戶。

下圖為登錄騰訊云服務(wù)端響應(yīng)頭截圖,cookie設(shè)置了相關(guān)的屬性:expirespath等。response headers服務(wù)端可以設(shè)置cookie 的所有選項(xiàng):expires、domain、pathsecure、HttpOnly。

image

  1. 客戶端設(shè)置 cookie

cookie不像web StoragesetItem,getItem,removeItem,clear等方法,需要自己封裝。簡(jiǎn)單地在瀏覽器的控制臺(tái)里輸入:

document.cookie="name=lynnshen; age=18"

image

最簡(jiǎn)單的設(shè)置多個(gè)cookie的方法就是重復(fù)執(zhí)行document.cookie = "key=name"

document.cookie = "name=lynnshen";
document.cookie = "age=18";

再看控制臺(tái):

image

5、Cookie設(shè)置、讀取、刪除方法的簡(jiǎn)單封裝

  1. 設(shè)置cookie
function setCookie(name, value, expires, path, domain, secure) {
    var cookieText = encodeURIComponent(name) + "=" +
    encodeURIComponent(value); 
    if (expires instanceof Date) {             
        cookieText += "; expires=" + expires.toGMTString();         
    } 
    if (path) {             
        cookieText += "; path=" + path;         
    } 
    if (domain) {            
        cookieText += "; domain=" + domain;        
    } 
    if (secure) {          
     cookieText += "; secure";      
    } 
    document.cookie = cookieText; 
}
  1. 刪除cookie
 function removeCookie(name, path, domain, secure){         
    this.set(name, "", new Date(0), path, domain, secure);    
 } 
 
  1. 讀取cookie
function getCookie(name){
    var cookieName = encodeURIComponent(name) + "=";         
    var cookieStart = document.cookie.indexOf(cookieName);
    var cookieValue = null; 
    if (cookieStart > -1){            
        var cookieEnd = document.cookie.indexOf(";", cookieStart);      
        if (cookieEnd == -1){                 
            cookieEnd = document.cookie.length;            
        }             
        cookieValue = decodeURIComponent(document.cookie.substring(
        cookieStart + cookieName.length, cookieEnd));     
    } 
    return cookieValue;     
 }

6、Cookie的缺點(diǎn)

  1. 每個(gè)特定域名下的cookie數(shù)量有限:

    • IE6或IE6-(IE6以下版本):最多20個(gè)cookie

    • IE7或IE7+(IE7以上版本):最多50個(gè)cookie

    • FF:最多50個(gè)cookie

    • Opera:最多30個(gè)cookie

    • Chrome和safari沒有硬性限制

當(dāng)超過單個(gè)域名限制之后,再設(shè)置cookie,瀏覽器就會(huì)清除以前設(shè)置的cookieIEOpera會(huì)清理近期最少使用的cookie,FF會(huì)隨機(jī)清理cookie

  1. 存儲(chǔ)量太小,只有4KB。

  2. 每次HTTP請(qǐng)求都會(huì)發(fā)送到服務(wù)端,影響獲取資源的效率。

  3. 需要自己封裝獲取、設(shè)置、刪除cookie的方法。

Web Storage

最初的Web Storage 規(guī)范包含了兩種對(duì)象的定義:sessionStorageglobalStorage。這兩個(gè)對(duì)象在支持的瀏覽器中都是以windows對(duì)象屬性的形式存在的。而localStorage對(duì)象在修訂過的HTML 5規(guī)范中作為持久保存客戶端數(shù)據(jù)的方案取代了
globalStorage。所以現(xiàn)在主要談?wù)摰氖?code>sessionStorage和localStorage兩種。

1、web Storage的主要作用:

  • 提供一種在 cookie 之外存儲(chǔ)會(huì)話數(shù)據(jù)的途徑;
  • 提供一種存儲(chǔ)大量可以跨會(huì)話存在的數(shù)據(jù)的機(jī)制。

2、web Storage 的主要方法:

  • clear(): 刪除所有值;Firefox 中沒有實(shí)現(xiàn) 。
  • getItem(name):根據(jù)指定的名字 name獲取對(duì)應(yīng)的值。
  • key(index):獲得 index 位置處的值的名字。
  • removeItem(name):刪除由 name 指定的名值對(duì)兒。

注意: Storage 類型只能存儲(chǔ)字符串。非字符串的數(shù)據(jù)在存儲(chǔ)之前會(huì)被轉(zhuǎn)換成字符串。

localStorage

1、localStorage的特點(diǎn)

  • 保存的數(shù)據(jù)長(zhǎng)期存在,下一次訪問該網(wǎng)站的時(shí)候,網(wǎng)頁(yè)可以直接讀取以前保存的數(shù)據(jù)。
  • 大小為5M左右
  • 僅在客戶端使用,不和服務(wù)端進(jìn)行通信
  • 接口封裝較好

基于上面的特點(diǎn),LocalStorage可以作為瀏覽器本地緩存方案,用來提升網(wǎng)頁(yè)首屏渲染速度(根據(jù)第一請(qǐng)求返回時(shí),將一些不變信息直接存儲(chǔ)在本地)。

2、localStorage的使用

//使用方法存儲(chǔ)數(shù)據(jù) 
localStorage.setItem("name", "Nicholas");

//使用屬性存儲(chǔ)數(shù)據(jù)
localStorage.book = "Professional JavaScript";

//使用方法讀取數(shù)據(jù)
var name = localStorage.getItem("name");

//使用屬性讀取數(shù)據(jù)
var book = localStorage.book;

數(shù)據(jù)的保留是通過 JavaScript 刪除或者是用戶清除瀏覽器緩存。

sessionStorage

1、什么是 sessionStorage ?

  • sessionStorage 對(duì)象存儲(chǔ)特定于某個(gè)會(huì)話的數(shù)據(jù),也就是該數(shù)據(jù)只保持到瀏覽器關(guān)閉。
  • sessionStorage就像會(huì)話 cookie,也會(huì)在瀏覽器關(guān)閉后消失。
  • 存儲(chǔ)在 sessionStorage中的數(shù)據(jù)可以跨越頁(yè)面刷新而存在,同時(shí)如果瀏覽器支持,瀏覽器崩潰并重啟之后依然可用(Firefox 和 WebKit都支持,IE則不行)。
  • seesionStorage對(duì)象綁定于某個(gè)服務(wù)器會(huì)話,所以當(dāng)文件在本地運(yùn)行的時(shí)候是不可用的。
  • 存儲(chǔ)在sessionStorage中的數(shù)據(jù)只能由最初給對(duì)象存儲(chǔ)數(shù)據(jù)的頁(yè)面訪問到,所以對(duì)多頁(yè)面應(yīng)用有限制。

2、sessionStorage的特點(diǎn):

  • 會(huì)話級(jí)別的瀏覽器存儲(chǔ)
  • 大小為5M左右
  • 僅在客戶端使用,不和服務(wù)端進(jìn)行通信
  • 接口封裝較好

基于上面的特點(diǎn),sessionStorage可以有效對(duì)表單信息進(jìn)行維護(hù),比如刷新時(shí),表單信息不丟失。

3、localStorage 的使用

//使用方法存儲(chǔ)數(shù)據(jù) 
sessionStorage.setItem("name", "Nicholas");

//使用屬性存儲(chǔ)數(shù)據(jù)
sessionStorage.book = "Professional JavaScript";

//使用方法讀取數(shù)據(jù)
var name = sessionStorage.getItem("name");

//使用屬性讀取數(shù)據(jù)
var book = sessionStorage.book;

sessionStorage 對(duì)象應(yīng)該主要用于僅針對(duì)會(huì)話的小段數(shù)據(jù)的存儲(chǔ)。如果需要跨越會(huì)話存儲(chǔ)數(shù)據(jù), 那么localStorage更為合適。

IndexedDB

1、IndexedDB 是什么?

Indexed Database API,或者簡(jiǎn)稱為IndexedDB,是在瀏覽器中保存結(jié)構(gòu)化數(shù)據(jù)的一種數(shù)據(jù)庫(kù)。IndexedDB 的思想是創(chuàng)建一套 API,方便保存和讀取 JavaScript 對(duì)象,同時(shí)還支持查詢及搜索。

2、IndexedDB 的特點(diǎn)

  • 鍵值對(duì)儲(chǔ)存IndexedDB 內(nèi)部采用對(duì)象倉(cāng)庫(kù)(object store)存放數(shù)據(jù)。所有類型的數(shù)據(jù)都可以直接存入,包括JavaScript對(duì)象。對(duì)象倉(cāng)庫(kù)中,數(shù)據(jù)以"鍵值對(duì)"的形式保存,每一個(gè)數(shù)據(jù)記錄都有對(duì)應(yīng)的主鍵,主鍵是獨(dú)一無二的,不能有重復(fù),否則會(huì)拋出一個(gè)錯(cuò)誤。
  • 異步:IndexedDB操作時(shí)不會(huì)鎖死瀏覽器,用戶依然可以進(jìn)行其他操作,這與 LocalStorage形成對(duì)比,后者的操作是同步的。異步設(shè)計(jì)是為了防止大量數(shù)據(jù)的讀寫,拖慢網(wǎng)頁(yè)的表現(xiàn)。
  • 支持事務(wù): IndexedDB支持事務(wù)(transaction),這意味著一系列操作步驟之中,只要有一步失敗,整個(gè)事務(wù)就都取消,數(shù)據(jù)庫(kù)回滾到事務(wù)發(fā)生之前的狀態(tài),不存在只改寫一部分?jǐn)?shù)據(jù)的情況。
  • 同源限制: IndexedDB受到同源限制,每一個(gè)數(shù)據(jù)庫(kù)對(duì)應(yīng)創(chuàng)建它的域名。網(wǎng)頁(yè)只能訪問自身域名下的數(shù)據(jù)庫(kù),而不能訪問跨域的數(shù)據(jù)庫(kù)。
  • 儲(chǔ)存空間大: IndexedDB 的儲(chǔ)存空間比 localStorage大得多,一般來說不少于 250MB,甚至沒有上限。
    -支持二進(jìn)制儲(chǔ)存: IndexedDB不僅可以儲(chǔ)存字符串,還可以儲(chǔ)存二進(jìn)制數(shù)據(jù)(ArrayBuffer 對(duì)象和 Blob 對(duì)象)。

3、IndexedDB 基本指令

  1. 建立打開IndexedDB : window.indexedDB.open("testDB")
  2. 關(guān)閉IndexedDB: indexdb.close()
  3. 刪除IndexedDB: window.indexedDB.deleteDatabase(indexdb)

4、webStorage、cookie 和 IndexedDB之間的區(qū)別

image

從上圖可以看到,cookie已經(jīng)不建議用于存儲(chǔ)。如果沒有大量數(shù)據(jù)存儲(chǔ)需求的話,可以使用 localStoragesessionStorage 。對(duì)于不怎么改變的數(shù)據(jù)盡量使用 localStorage 存儲(chǔ),否則可以用 sessionStorage 存儲(chǔ)。

總結(jié)

web存儲(chǔ)可以說是必須要重點(diǎn)理解和掌握的知識(shí)點(diǎn)了,特別是web Storage經(jīng)常會(huì)使用到。最后總結(jié)用一句話總結(jié)三種存儲(chǔ)方案。

  • Cookie 的本職工作并非本地存儲(chǔ),而是“維持狀態(tài)”。
  • Web Storage 是 HTML5專門為瀏覽器存儲(chǔ)而提供的數(shù)據(jù)存儲(chǔ)機(jī)制,不與服務(wù)端發(fā)生通信。
  • IndexedDB 用于客戶端存儲(chǔ)大量結(jié)構(gòu)化數(shù)據(jù)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ??支持離線 Web 應(yīng)用開發(fā)是 HTML5 的另一個(gè)重點(diǎn)。 ??所謂離線 Web 應(yīng)用,就是在設(shè)備不能上網(wǎng)的情況...
    霜天曉閱讀 1,185評(píng)論 0 2
  • 前言: 五一假期在擼代碼的時(shí)候用到cookie,感覺對(duì)瀏覽器的數(shù)據(jù)存儲(chǔ)方案不是很了解,因此又去翻了兩本大頭書中間的...
    Srtian閱讀 5,312評(píng)論 6 86
  • 我靜靜地看著你, 在如火的夕陽(yáng)中, 望著你修長(zhǎng)的身影。 天空, 好似凝固了的血。 我站在天橋上, 默默地說一句 :...
    無元再見閱讀 363評(píng)論 0 3
  • 文能抒意,亦能怡情,所謂“詩(shī)必仿盛唐,詞必學(xué)兩宋,曲必同元風(fēng),文必效魏晉,”此古人之成見,非今日之應(yīng)...
    理想者的執(zhí)念閱讀 565評(píng)論 2 12
  • 紅旗搖曳 軍歌嘹亮 上至耄耋 下至玩童 都把心聲唱響 獻(xiàn)給母親最美的詩(shī)行 別樣的日子...
    風(fēng)雨之后的彩虹閱讀 220評(píng)論 0 4

友情鏈接更多精彩內(nèi)容