深入理解瀏覽器存儲

前言

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

Cookie

1退盯、Cookie是什么?

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

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

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

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

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

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

  • name(名稱):一個唯一確定cookie的名稱剃允。cookie的名稱必須是經(jīng)過 URL編碼的。
  • value(值):儲存在 cookie中的字符串值齐鲤。值必須被 URL編碼斥废。
  • Domain(域):cookie 對于哪個域是有效的。所有向該域發(fā)送的請求中都會包含這個 cookie 信息给郊。
  • path(路徑):對于指定域中的那個路徑牡肉,應(yīng)該向服務(wù)器發(fā)送 cookie
  • Expires/Max-Age(失效時間):表示 cookie 何時應(yīng)該被刪除的時間戳(也就是淆九,何時應(yīng)該停止向服務(wù)器發(fā)送這個 cookie)统锤。
  • HttpOnly:這個屬性是面試的時候常考的炭庙,如果這個屬性設(shè)置為true饲窿,就不能通過js腳本來獲取cookie的值,能有效的防止xss攻擊焕蹄。
  • Secure(安全標(biāo)志):指定后逾雄,cookie 只有在使用 SSL 連接的時候才發(fā)送到服務(wù)器。
image

3擦盾、Cookie的原理

image

第一次訪問網(wǎng)站的時候嘲驾,瀏覽器發(fā)出請求,服務(wù)器響應(yīng)請求后迹卢,會在響應(yīng)頭里面添加一個Set-Cookie辽故,將cookie放入到響應(yīng)請求中,在瀏覽器第二次發(fā)請求的時候腐碱,會通過Cookie請求頭部將Cookie信息發(fā)送給服務(wù)器誊垢,服務(wù)端會辨別用戶身份掉弛,另外,Cookie的過期時間喂走、域殃饿、路徑、有效期芋肠、適用站點都可以根據(jù)需要來指定乎芳。

4、Cookie生成方式

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

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

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

下圖為登錄騰訊云服務(wù)端響應(yīng)頭截圖睡汹,cookie設(shè)置了相關(guān)的屬性:expires肴甸、path等。response headers服務(wù)端可以設(shè)置cookie 的所有選項:expires囚巴、domain原在、pathsecure彤叉、HttpOnly庶柿。

image

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

cookie不像web StoragesetItemgetItem姆坚,removeItem澳泵,clear等方法实愚,需要自己封裝兼呵。簡單地在瀏覽器的控制臺里輸入:

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

image

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

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

再看控制臺:

image

5、Cookie設(shè)置腊敲、讀取击喂、刪除方法的簡單封裝

  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的缺點

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

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

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

    • FF:最多50個cookie

    • Opera:最多30個cookie

    • Chrome和safari沒有硬性限制

當(dāng)超過單個域名限制之后碰辅,再設(shè)置cookie懂昂,瀏覽器就會清除以前設(shè)置的cookieIEOpera會清理近期最少使用的cookie没宾,FF會隨機(jī)清理cookie凌彬。

  1. 存儲量太小,只有4KB循衰。

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

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

Web Storage

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

1焙畔、web Storage的主要作用:

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

2、web Storage 的主要方法:

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

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

localStorage

1砌烁、localStorage的特點

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

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

2捐下、localStorage的使用

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

//使用屬性存儲數(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 對象存儲特定于某個會話的數(shù)據(jù)奸柬,也就是該數(shù)據(jù)只保持到瀏覽器關(guān)閉。
  • sessionStorage就像會話 cookie婴程,也會在瀏覽器關(guān)閉后消失廓奕。
  • 存儲在 sessionStorage中的數(shù)據(jù)可以跨越頁面刷新而存在,同時如果瀏覽器支持档叔,瀏覽器崩潰并重啟之后依然可用(Firefox 和 WebKit都支持桌粉,IE則不行)。
  • seesionStorage對象綁定于某個服務(wù)器會話衙四,所以當(dāng)文件在本地運(yùn)行的時候是不可用的铃肯。
  • 存儲在sessionStorage中的數(shù)據(jù)只能由最初給對象存儲數(shù)據(jù)的頁面訪問到,所以對多頁面應(yīng)用有限制届搁。

2缘薛、sessionStorage的特點:

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

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

3恕齐、localStorage 的使用

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

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

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

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

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

IndexedDB

1仪或、IndexedDB 是什么?

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

2巨缘、IndexedDB 的特點

  • 鍵值對儲存IndexedDB 內(nèi)部采用對象倉庫(object store)存放數(shù)據(jù)添忘。所有類型的數(shù)據(jù)都可以直接存入,包括JavaScript對象若锁。對象倉庫中搁骑,數(shù)據(jù)以"鍵值對"的形式保存,每一個數(shù)據(jù)記錄都有對應(yīng)的主鍵又固,主鍵是獨(dú)一無二的仲器,不能有重復(fù),否則會拋出一個錯誤口予。
  • 異步:IndexedDB操作時不會鎖死瀏覽器娄周,用戶依然可以進(jìn)行其他操作涕侈,這與 LocalStorage形成對比沪停,后者的操作是同步的。異步設(shè)計是為了防止大量數(shù)據(jù)的讀寫裳涛,拖慢網(wǎng)頁的表現(xiàn)木张。
  • 支持事務(wù): IndexedDB支持事務(wù)(transaction),這意味著一系列操作步驟之中端三,只要有一步失敗舷礼,整個事務(wù)就都取消,數(shù)據(jù)庫回滾到事務(wù)發(fā)生之前的狀態(tài)郊闯,不存在只改寫一部分?jǐn)?shù)據(jù)的情況妻献。
  • 同源限制: IndexedDB受到同源限制蛛株,每一個數(shù)據(jù)庫對應(yīng)創(chuàng)建它的域名。網(wǎng)頁只能訪問自身域名下的數(shù)據(jù)庫育拨,而不能訪問跨域的數(shù)據(jù)庫谨履。
  • 儲存空間大: IndexedDB 的儲存空間比 localStorage大得多,一般來說不少于 250MB熬丧,甚至沒有上限笋粟。
    -支持二進(jìn)制儲存: IndexedDB不僅可以儲存字符串,還可以儲存二進(jìn)制數(shù)據(jù)(ArrayBuffer 對象和 Blob 對象)析蝴。

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)不建議用于存儲。如果沒有大量數(shù)據(jù)存儲需求的話佑菩,可以使用 localStoragesessionStorage 东涡。對于不怎么改變的數(shù)據(jù)盡量使用 localStorage 存儲,否則可以用 sessionStorage 存儲倘待。

總結(jié)

web存儲可以說是必須要重點理解和掌握的知識點了疮跑,特別是web Storage經(jīng)常會使用到。最后總結(jié)用一句話總結(jié)三種存儲方案凸舵。

  • Cookie 的本職工作并非本地存儲祖娘,而是“維持狀態(tài)”。
  • Web Storage 是 HTML5專門為瀏覽器存儲而提供的數(shù)據(jù)存儲機(jī)制啊奄,不與服務(wù)端發(fā)生通信渐苏。
  • IndexedDB 用于客戶端存儲大量結(jié)構(gòu)化數(shù)據(jù)。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末菇夸,一起剝皮案震驚了整個濱河市琼富,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌庄新,老刑警劉巖鞠眉,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異择诈,居然都是意外死亡械蹋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門羞芍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哗戈,“玉大人,你說我怎么就攤上這事荷科∥ㄒВ” “怎么了纱注?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胆胰。 經(jīng)常有香客問我奈附,道長,這世上最難降的妖魔是什么煮剧? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任斥滤,我火速辦了婚禮,結(jié)果婚禮上勉盅,老公的妹妹穿的比我還像新娘佑颇。我一直安慰自己,他們只是感情好草娜,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布挑胸。 她就那樣靜靜地躺著,像睡著了一般宰闰。 火紅的嫁衣襯著肌膚如雪茬贵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天移袍,我揣著相機(jī)與錄音解藻,去河邊找鬼。 笑死葡盗,一個胖子當(dāng)著我的面吹牛螟左,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播觅够,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼胶背,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了喘先?” 一聲冷哼從身側(cè)響起钳吟,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窘拯,沒想到半個月后红且,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡树枫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年直焙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砂轻。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖斤吐,靈堂內(nèi)的尸體忽然破棺而出搔涝,到底是詐尸還是另有隱情厨喂,我是刑警寧澤,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布庄呈,位于F島的核電站蜕煌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏诬留。R本人自食惡果不足惜斜纪,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望文兑。 院中可真熱鬧盒刚,春花似錦、人聲如沸绿贞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽籍铁。三九已至涡上,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拒名,已是汗流浹背吩愧。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留增显,地道東北人耻警。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像甸怕,于是被迫代替她去往敵國和親甘穿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

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