瀏覽器的「Web存儲(chǔ)」與「應(yīng)用緩存」

HTML5 在客戶(hù)端存儲(chǔ)上推出的兩種新方法。之前都是由cookie完成宅荤, 但是cookie并不適合做大量數(shù)據(jù)的存儲(chǔ)屑迂,嚴(yán)重影響數(shù)據(jù)傳輸效率。但cookie能實(shí)現(xiàn)跨域(在請(qǐng)求上由請(qǐng)求決定)冯键,而他們不能惹盼,這里先不談這點(diǎn)。

* Web存儲(chǔ)有兩種方式: localStorage 和 sessionStorage

localStorage定義

?網(wǎng)上常解釋?zhuān)簂ocalStorage 用于持久化的本地存儲(chǔ)惫确,除非主動(dòng)刪除數(shù)據(jù)手报,否則數(shù)據(jù)是永遠(yuǎn)不會(huì)過(guò)期「幕總感覺(jué)還沒(méi)明白掩蛤,我理解是:localStorage 是一種持久化的存儲(chǔ),它能將數(shù)據(jù)存儲(chǔ)到本地硬盤(pán)當(dāng)中陈肛,因此數(shù)據(jù)沒(méi)有時(shí)間限制揍鸟,不會(huì)因?yàn)橐淮螘?huì)話(huà)結(jié)束或關(guān)機(jī)等操作而消失,除非我們主動(dòng)清除句旱。

localStorage 的使用

localStoragesetItem()方法來(lái)設(shè)置值阳藻,用 getItem() 方法獲取值。
html代碼

<div id="result"></div>

javascript代碼

// 檢查瀏覽器支持性
if ( typeof(Storage)  && typeof(localStorage) ) {
  // 添加值
  localStorage.setItem("sayHi", "Hello World!");
  // 取值
  document.getElementById("result").innerHTML = localStorage.getItem("sayHi");
} else {
  document.getElementById("result").innerHTML = "您的瀏覽器不支持 Web Storage ...";
}

效果展示


代碼解釋?zhuān)?/em> typeof(Storage) 將輸出function谈撒, typeof(localStorage) 將輸出Object腥泥,也有說(shuō)要添加 typeof(window.localStorage)的。增強(qiáng)檢測(cè)啃匿,我覺(jué)得沒(méi)太大必要道川。另外,localStorage其實(shí)就是一個(gè)對(duì)象立宜,因此我們存儲(chǔ),都是往這個(gè)對(duì)象中增加鍵值對(duì)而已臊岸。

localStorage數(shù)據(jù)的“全局性“

? 此處說(shuō)全局性橙数,大家可別以為是全局變量,這是不同的概念帅戒。localStorage的數(shù)據(jù)就數(shù)據(jù)本身來(lái)說(shuō)灯帮,其實(shí)是脫離程序而存在的(磁盤(pán)中不同的程序所產(chǎn)生的localStorage會(huì)被分離存放崖技,不會(huì)互相干擾),那么钟哥,它就不受程序作用域范圍的限制迎献,即,擁有全局性腻贰。既然如此吁恍,我們可以有以下用法:

統(tǒng)計(jì)用戶(hù)頁(yè)面訪問(wèn)次數(shù)
html代碼

<div class="box">
  <p>當(dāng)前訪問(wèn)人次:<span id="views"></span></p>
  <p>TIP:關(guān)閉或刷新,訪問(wèn)次數(shù)會(huì)增加播演。</p>
</div>

javascript代碼

if (localStorage.views) {
  localStorage.views = Number(localStorage.views) + 1;
} else {
  localStorage.setItem("views", 1);
}

document.getElementById("views").innerHTML = localStorage.views;

效果展示


sessionStorage 定義

?關(guān)于sessionStorage的解釋都比較統(tǒng)一:sessionStorage方法 針對(duì)一個(gè) session【會(huì)話(huà)】進(jìn)行數(shù)據(jù)存儲(chǔ)冀瓦。當(dāng)用戶(hù)關(guān)閉瀏覽器窗口后,數(shù)據(jù)會(huì)被刪除写烤。sessionStorage數(shù)據(jù)信息是存儲(chǔ)在內(nèi)存中的翼闽。

sessionStorage 的使用

?sessionStoragelocalStorage的用法類(lèi)似,也有setItem()getItem()洲炊。

?下面我們來(lái)看一個(gè)案例
html代碼

<div class="box">
  <button id="click">點(diǎn)擊計(jì)數(shù)</button>
  <p>當(dāng)前計(jì)數(shù):<span id="views"></span></p>
</div>

javascript代碼

if (sessionStorage.views) {
  // todo
} else {
  sessionStorage.setItem("views", 1);
}
document.getElementById("click").onclick = function() {
  sessionStorage.views = Number(sessionStorage.views) + 1;
  document.getElementById("views").innerHTML = sessionStorage.views;
}

效果展示

在該案例中感局,我們用dom操作給 views 綁定了點(diǎn)擊事件,每次點(diǎn)擊暂衡,增加一個(gè)計(jì)數(shù)询微,變量存放在session中。

驗(yàn)證什么是一次「會(huì)話(huà)」

看這個(gè)例子
html代碼

<div class="box">
  <button id="click">點(diǎn)擊計(jì)數(shù)</button>
  <p>當(dāng)前訪問(wèn)人次:<span id="views"></span></p>
  <p>TIP:刷新古徒,訪問(wèn)次數(shù)會(huì)增加拓提;關(guān)閉頁(yè)面,訪問(wèn)次數(shù)會(huì)重置隧膘。</p>
</div>

javascript代碼

if (sessionStorage.views) {
  sessionStorage.views = Number(sessionStorage.views) + 1;
} else {
  sessionStorage.setItem("views", 1);
}

document.getElementById("views").innerHTML = sessionStorage.views;

效果展示


?
?所以說(shuō):一次會(huì)話(huà)是指:用戶(hù)打開(kāi)瀏覽器代态,點(diǎn)擊多個(gè)超鏈接,訪問(wèn)Web服務(wù)器上的資源疹吃,然后關(guān)閉瀏覽器蹦疑,整個(gè)過(guò)程稱(chēng)之為一次會(huì)話(huà)。也就是說(shuō)萨驶,刷新不會(huì)提前關(guān)閉會(huì)話(huà)歉摧。

關(guān)于瀏覽器存儲(chǔ),大致就這些腔呜,接下來(lái)我們?cè)诳纯礊g覽器緩存
?

* 應(yīng)用緩存 - 瀏覽器緩存

什么是應(yīng)用緩存叁温?

「緩存」 就是當(dāng)你打開(kāi)一個(gè)網(wǎng)頁(yè)時(shí),瀏覽器會(huì)自動(dòng)下載副本到本地電腦上核畴,感覺(jué)就像是你“另存為“一個(gè)網(wǎng)頁(yè)到某個(gè)地方膝但。瀏覽器也不是把所有的網(wǎng)頁(yè)都緩存到本地,一般htmlget請(qǐng)求會(huì)緩存谤草,而post就不緩存跟束。

控制是否緩存

?1. 客戶(hù)端是否需要緩存能夠在服務(wù)器端的 響應(yīng)頭上控制莺奸,響應(yīng)頭告訴緩存器不要保留緩存,緩存器就不會(huì)緩存相應(yīng)內(nèi)容冀宴;
?2. 如果請(qǐng)求信息是需要認(rèn)證或者安全加密的灭贷,相應(yīng)內(nèi)容也不會(huì)被緩存;

HTML 5 緩存

HTML 5引入了應(yīng)用緩存【Application Cache】略贮,它能實(shí)現(xiàn)在沒(méi)有因特網(wǎng)連接時(shí)進(jìn)行訪問(wèn)甚疟。它有三個(gè)優(yōu)勢(shì):

  • 離線瀏覽 - 用戶(hù)可以在應(yīng)用離線時(shí)使用它們。
  • 速度 - 已緩存資源加載速度更快刨肃。
  • 減少服務(wù)器負(fù)載 - 瀏覽器將只從服務(wù)器上下載更新過(guò)或更改過(guò)的資源古拴。

如果需要啟用應(yīng)用程序緩存,請(qǐng)?jiān)谖臋n的<html>標(biāo)簽中包含 manifest 屬性:

<DOCTYPE HTML>
<html manifest="demo.appcache">
...
</html>

如上指定了manifest的html文件將會(huì)被緩存真友,未對(duì)其進(jìn)行指定的頁(yè)面不被緩存黄痪。也可以在manifest文件中直接指定該頁(yè)面。
manifest文件的建議拓展名為.appcache盔然。
請(qǐng)注意桅打, manifest 文件需要配置正確的MIME-type,即"text/cache-manifest"必須在 web服務(wù)器上進(jìn)行配置愈案。


MANIFEST.appcache 文件

?manifest 文件是簡(jiǎn)單的文本文件挺尾,結(jié)構(gòu)非常簡(jiǎn)單,它告知瀏覽器什內(nèi)容需要緩存站绪,什么內(nèi)容不需要緩存遭铺。
由以下三個(gè)部分構(gòu)成:

  • CACHE MANIFEST - 在此目錄下列出的文件將在首次下載后進(jìn)行緩存。
  • NETWORK - 在此標(biāo)題下列出的文件需要與服務(wù)器交互獲取恢准,不進(jìn)行緩存魂挂。
  • FALLBACK - 該標(biāo)題下列出的文件規(guī)定當(dāng)頁(yè)面無(wú)法訪問(wèn)時(shí)的回退頁(yè)面(比如404頁(yè)面)
  • manifest文件完整實(shí)例*:
CACHE MANIFEST
# 2012-02-21 v1.0.0
/theme.css
/logo.fig
/main.js

NETWORK:
login.html

FALLBACK:
/html5/ /404.html    // 前者是資源URI, 后者是代替頁(yè)面

說(shuō)明:

  • 以 # 開(kāi)頭的是注釋行馁筐,但也可以滿(mǎn)足其他需求涂召。應(yīng)用緩存會(huì)在器 manifest 文件被更改的時(shí)候更新。如果您編輯了一副圖片敏沉,或者修改了一個(gè)javascript函數(shù)果正,這些改變都不會(huì)被重新緩存。這時(shí)候盟迟,更新注釋行中的日期和版本號(hào)是一種使瀏覽器重新緩存文件的非常好的辦法秋泳。
  • NETWORK 可以使用星號(hào)來(lái)指示所有其他資源/文件都需要因特網(wǎng)連接,如
NETWORK:
*
  • 更新緩存:
    1. 用戶(hù)在瀏覽器上自己清空緩存。
    2. manifest 文件被修改攒菠。
    3. 由程序來(lái)更新應(yīng)用緩存轮锥。
經(jīng)常遇到的困擾:

? 一旦文件被緩存,則瀏覽器會(huì)繼續(xù)展示已緩存的版本要尔。你可能會(huì)遇到舍杜,服務(wù)器上已經(jīng)更新了代碼,但瀏覽器依舊顯示舊的內(nèi)容赵辕,而且已經(jīng)向CDN多次推新的資源也沒(méi)用既绩。 其實(shí)這時(shí)候就是因?yàn)闉g覽器緩存了的原因。你需要更新一下manifest文件还惠。一般瀏覽器設(shè)置的限制緩存是5M饲握。

?

* 從瀏覽器角度看緩存

借用網(wǎng)絡(luò)上的一張圖片:



我們來(lái)細(xì)說(shuō)兩個(gè)校驗(yàn)參數(shù):

Last-Modified 和 ETag

1. Last-Modified 工作原理
?在瀏覽器第一次請(qǐng)求某一個(gè)URL時(shí),服務(wù)器端的返回狀態(tài)會(huì)是200蚕键,內(nèi)容是你請(qǐng)求的資源救欧,同時(shí)有一個(gè)Last-Modified的屬性標(biāo)記(HttpReponse Header)此文件在服務(wù)期端最后被修改的時(shí)間.
?格式:Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT

?客戶(hù)端第二次請(qǐng)求此URL時(shí),根據(jù)HTTP協(xié)議的規(guī)定锣光,瀏覽器會(huì)向服務(wù)器發(fā)送If-Modified-Since報(bào)頭(HttpRequest Header)笆怠,詢(xún)問(wèn)該時(shí)間之后文件是否有被修改過(guò):
?格式:If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT

?如果服務(wù)器端的資源沒(méi)有變化,則自動(dòng)返回HTTP304(NotChanged.)狀態(tài)碼誊爹,內(nèi)容為空蹬刷,這樣就節(jié)省了傳輸數(shù)據(jù)量。當(dāng)服務(wù)器端代碼發(fā)生改變或者重啟服務(wù)器時(shí)频丘,則重新發(fā)出資源办成,返回和第一次請(qǐng)求時(shí)類(lèi)似。從而保證不向客戶(hù)端重復(fù)發(fā)出資源搂漠,也保證當(dāng)服務(wù)器有變化時(shí)迂卢,客戶(hù)端能夠得到最新的資源。

注:如果If-Modified-Since的時(shí)間比服務(wù)器當(dāng)前時(shí)間(當(dāng)前的請(qǐng)求時(shí)間request_time)還晚桐汤,會(huì)認(rèn)為是個(gè)非法請(qǐng)求而克。

2. ETag 工作原理
?HTTP協(xié)議規(guī)格說(shuō)明定義ETag為“被請(qǐng)求變量的實(shí)體標(biāo)記”,簡(jiǎn)單說(shuō)即服務(wù)器響應(yīng)時(shí)給請(qǐng)求URL標(biāo)記惊科,并在HTTP響應(yīng)頭中將其傳送到客戶(hù)端拍摇,類(lèi)似服務(wù)器端返回的格式:
?格式:Etag:“5d8c72a5edda8d6a:3239″

?客戶(hù)端的查詢(xún)更新格式是這樣的:
?格式:If-None-Match:“5d8c72a5edda8d6a:3239″
如果ETag沒(méi)改變,則返回狀態(tài)304馆截。
即:在客戶(hù)端發(fā)出請(qǐng)求后充活,HttpReponse Header中包含Etag:“5d8c72a5edda8d6a:3239″標(biāo)識(shí),等于告訴Client端蜡娶,你拿到的這個(gè)的資源有表示ID:5d8c72a5edda8d6a:3239混卵。當(dāng)下次需要發(fā)Request索要同一個(gè)URI的時(shí)候,瀏覽器同時(shí)發(fā)出一個(gè)If-None-Match報(bào)頭(Http RequestHeader)此時(shí)包頭中信息包含上次訪問(wèn)得到的Etag:“5d8c72a5edda8d6a:3239″標(biāo)識(shí)窖张。
?格式:If-None-Match:“5d8c72a5edda8d6a:3239“

?這樣幕随,Client端等于Cache了兩份,服務(wù)器端就會(huì)比對(duì)2者的etag宿接。如果If-None-Match為False赘淮,不返回200辕录,返回304(Not Modified) Response。

就介紹這些梢卸,如果有錯(cuò)誤走诞,歡迎指正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛤高,一起剝皮案震驚了整個(gè)濱河市蚣旱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戴陡,老刑警劉巖塞绿,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異恤批,居然都是意外死亡异吻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)开皿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涧黄,“玉大人,你說(shuō)我怎么就攤上這事赋荆∷裢祝” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵窄潭,是天一觀的道長(zhǎng)春宣。 經(jīng)常有香客問(wèn)我,道長(zhǎng)嫉你,這世上最難降的妖魔是什么月帝? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮幽污,結(jié)果婚禮上嚷辅,老公的妹妹穿的比我還像新娘。我一直安慰自己距误,他們只是感情好簸搞,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著准潭,像睡著了一般趁俊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上刑然,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天寺擂,我揣著相機(jī)與錄音,去河邊找鬼。 笑死怔软,一個(gè)胖子當(dāng)著我的面吹牛垦细,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挡逼,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蝠检,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了挚瘟?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饲梭,失蹤者是張志新(化名)和其女友劉穎乘盖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體憔涉,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡订框,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了兜叨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穿扳。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖国旷,靈堂內(nèi)的尸體忽然破棺而出矛物,到底是詐尸還是另有隱情,我是刑警寧澤跪但,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布履羞,位于F島的核電站,受9級(jí)特大地震影響屡久,放射性物質(zhì)發(fā)生泄漏忆首。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一被环、第九天 我趴在偏房一處隱蔽的房頂上張望糙及。 院中可真熱鬧,春花似錦筛欢、人聲如沸浸锨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)揣钦。三九已至,卻和暖如春漠酿,著一層夾襖步出監(jiān)牢的瞬間冯凹,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宇姚,地道東北人匈庭。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像浑劳,于是被迫代替她去往敵國(guó)和親阱持。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351

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