前言
隨著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-Cookie
而HTTP
頭作為響應(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ù)器。
3擦盾、Cookie的原理
第一次訪問網(wǎng)站的時候嘲驾,瀏覽器發(fā)出請求,服務(wù)器響應(yīng)請求后迹卢,會在響應(yīng)頭里面添加一個
Set-Cookie
辽故,將cookie
放入到響應(yīng)請求中,在瀏覽器第二次發(fā)請求的時候腐碱,會通過Cookie
請求頭部將Cookie
信息發(fā)送給服務(wù)器誊垢,服務(wù)端會辨別用戶身份掉弛,另外,Cookie
的過期時間喂走、域殃饿、路徑、有效期芋肠、適用站點都可以根據(jù)需要來指定乎芳。
4、Cookie生成方式
Cookie的生成方式主要有兩種:
- 服務(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
原在、path
、secure
彤叉、HttpOnly
庶柿。
- 客戶端設(shè)置 cookie
cookie
不像web Storage
有setItem
,getItem
姆坚,removeItem
澳泵,clear
等方法实愚,需要自己封裝兼呵。簡單地在瀏覽器的控制臺里輸入:
document.cookie="name=lynnshen; age=18"
最簡單的設(shè)置多個
cookie
的方法就是重復(fù)執(zhí)行document.cookie = "key=name"
document.cookie = "name=lynnshen";
document.cookie = "age=18";
再看控制臺:
5、Cookie設(shè)置腊敲、讀取击喂、刪除方法的簡單封裝
- 設(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;
}
- 刪除cookie
function removeCookie(name, path, domain, secure){
this.set(name, "", new Date(0), path, domain, secure);
}
- 讀取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的缺點
-
每個特定域名下的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è)置的cookie
。IE
和Opera
會清理近期最少使用的cookie
没宾,FF
會隨機(jī)清理cookie
凌彬。
存儲量太小,只有
4KB
循衰。每次
HTTP
請求都會發(fā)送到服務(wù)端铲敛,影響獲取資源的效率。需要自己封裝獲取会钝、設(shè)置伐蒋、刪除
cookie
的方法。
Web Storage
最初的Web Storage
規(guī)范包含了兩種對象的定義:sessionStorage
和globalStorage
。這兩個對象在支持的瀏覽器中都是以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 基本指令
- 建立打開IndexedDB :
window.indexedDB.open("testDB")
- 關(guān)閉IndexedDB:
indexdb.close()
- 刪除IndexedDB:
window.indexedDB.deleteDatabase(indexdb)
4、webStorage闷畸、cookie 和 IndexedDB之間的區(qū)別
從上圖可以看到尝盼,
cookie
已經(jīng)不建議用于存儲。如果沒有大量數(shù)據(jù)存儲需求的話佑菩,可以使用 localStorage
和 sessionStorage
东涡。對于不怎么改變的數(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ù)。