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 的使用
localStorage
用 setItem()
方法來(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 的使用
?sessionStorage
與localStorage
的用法類(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è)都緩存到本地,一般html
或get請(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ò)誤走诞,歡迎指正。