原文鏈接:https://www.cnblogs.com/shoestrong/p/6435169.html
最近由于找工作一直沒時(shí)間也沒有精力更新博客蔚舀,找工作真是一件苦逼的事情啊思币。娩缰。甚亭。不抱怨了唯鸭,我們來看看HTML5的新特性---離線存儲(chǔ)吧盼忌。
隨著Web App的發(fā)展再愈,越來越多的移動(dòng)端App使用HTML5的方式來開發(fā)奠伪,除了一些HybridApp以外跌帐,其他一部分Web App還是通過瀏覽器來訪問的,通過瀏覽器訪問就需要聯(lián)網(wǎng)發(fā)送請(qǐng)求绊率,這樣就使得用戶在離線的狀態(tài)下無法使用App谨敛,同時(shí)Web App中一部分資源并不是經(jīng)常改變,并不需要每次都向服務(wù)器發(fā)出請(qǐng)求滤否,出于這些原因脸狸,HTML5提出的一個(gè)新的特性:離線存儲(chǔ)。通過離線存儲(chǔ),我們可以通過把需要離線存儲(chǔ)在本地的文件列在一個(gè)manifest配置文件中炊甲,這樣即使在離線的情況下泥彤,用戶也可以正常使用App。
怎么用
首先來講解下離線存儲(chǔ)的使用方法卿啡,說起來也很簡(jiǎn)單吟吝。只要在你的頁(yè)面頭部像下面一樣加入一個(gè)manifest
的屬性就可以了。
<!DOCTYPE HTML>
<html manifest = "cache.manifest">
...
</html>
然后cache.manifest
文件的書寫方式颈娜,就像下面這樣:
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
/ /offline.html
離線存儲(chǔ)的manifest一般由三個(gè)部分組成:
1.CACHE:表示需要離線存儲(chǔ)的資源列表剑逃,由于包含manifest文件的頁(yè)面將被自動(dòng)離線存儲(chǔ),所以不需要把頁(yè)面自身也列出來官辽。
2.NETWORK:表示在它下面列出來的資源只有在在線的情況下才能訪問炕贵,他們不會(huì)被離線存儲(chǔ),所以在離線情況下無法使用這些資源野崇。不過,如果在CACHE和NETWORK中有一個(gè)相同的資源亩钟,那么這個(gè)資源還是會(huì)被離線存儲(chǔ)乓梨,也就是說CACHE的優(yōu)先級(jí)更高。
3.FALLBACK:表示如果訪問第一個(gè)資源失敗清酥,那么就使用第二個(gè)資源來替換他扶镀,比如上面這個(gè)文件表示的就是如果訪問根目錄下任何一個(gè)資源失敗了,那么就去訪問offline.html焰轻。
瀏覽器怎么解析manifest
那么瀏覽器是怎么對(duì)離線的資源進(jìn)行管理和加載的呢臭觉?這里需要分兩種情況來討論。
在線的情況下辱志,瀏覽器發(fā)現(xiàn)html頭部有manifest屬性蝠筑,它會(huì)請(qǐng)求manifest文件,如果是第一次訪問app揩懒,那么瀏覽器就會(huì)根據(jù)manifest文件的內(nèi)容下載相應(yīng)的資源并且進(jìn)行離線存儲(chǔ)什乙。如果已經(jīng)訪問過app并且資源已經(jīng)離線存儲(chǔ)了,那么瀏覽器就會(huì)使用離線的資源加載頁(yè)面已球,然后瀏覽器會(huì)對(duì)比新的manifest文件與舊的manifest文件臣镣,如果文件沒有發(fā)生改變,就不做任何操作智亮,如果文件改變了忆某,那么就會(huì)重新下載文件中的資源并進(jìn)行離線存儲(chǔ)。
離線的情況下阔蛉,瀏覽器就直接使用離線存儲(chǔ)的資源弃舒。
這個(gè)過程中有幾個(gè)問題需要注意。
如果服務(wù)器對(duì)離線的資源進(jìn)行了更新馍忽,那么必須更新manifest文件之后這些資源才能被瀏覽器重新下載棒坏,如果只是更新了資源而沒有更新manifest文件的話燕差,瀏覽器并不會(huì)重新下載資源,也就是說還是使用原來離線存儲(chǔ)的資源坝冕。
對(duì)于manifest文件進(jìn)行緩存的時(shí)候需要十分小心徒探,因?yàn)榭赡艹霈F(xiàn)一種情況就是你對(duì)manifest文件進(jìn)行了更新,但是http的緩存規(guī)則告訴瀏覽器本地緩存的manifest文件還沒過期喂窟,這個(gè)情況下瀏覽器還是使用原來的manifest文件测暗,所以對(duì)于manifest文件最好不要設(shè)置緩存。
瀏覽器在下載manifest文件中的資源的時(shí)候磨澡,它會(huì)一次性下載所有資源碗啄,如果某個(gè)資源由于某種原因下載失敗,那么這次的所有更新就算是失敗的稳摄,瀏覽器還是會(huì)使用原來的資源稚字。
在更新了資源之后,新的資源需要到下次再打開app才會(huì)生效厦酬,如果需要資源馬上就能生效胆描,那么可以使用
window.applicationCache.swapCache()
方法來使之生效,出現(xiàn)這種現(xiàn)象的原因是瀏覽器會(huì)先使用離線資源加載頁(yè)面仗阅,然后再去檢查manifest是否有更新昌讲,所以需要到下次打開頁(yè)面才能生效。
咱們來試試吧
說了這么多减噪,不如自己動(dòng)手來試試短绸。這里需要說明的是,如果需要看到離線存儲(chǔ)的效果筹裕,那么你需要把你的網(wǎng)頁(yè)部署到服務(wù)器上醋闭,不管是本地還是生產(chǎn)環(huán)境服務(wù)器中,通過本地文件打開網(wǎng)頁(yè)是無法體驗(yàn)到離線存儲(chǔ)的饶碘。我在我的電腦上跑了一個(gè)本地node服務(wù)器目尖,通過localhost訪問。我的manifest文件向下面這樣:
CACHE MANIFEST
#v0.11
CACHE:
lib/ionic/js/ionic.bundle.js
lib/angular-ui-router.js
js/app.js
lib/ionic/css/ionic.css
css/style.css
views/login_header.html
views/login.html
lib/ionic/fonts/ionicons.ttf?v=1.5.2
lib/ionic/fonts/ionicons.woff?v=1.5.2
NETWORK:
lib/ionic/fonts/ionicons.ttf?v=1.5.2
lib/ionic/fonts/ionicons.woff?v=1.5.2
css/style.css
然后我們?cè)L問網(wǎng)頁(yè)看看效果扎运。
可以看出瀏覽器根據(jù)manifest文件下載相應(yīng)資源并且緩存在本地瑟曲,現(xiàn)在我們來試試再次訪問網(wǎng)頁(yè)
資源已經(jīng)離線存儲(chǔ)在本地,所以瀏覽器不需要再次下載資源豪治,可以直接使用本地緩存的資源洞拨。接著,我們更新下服務(wù)器上的資源负拟,比如我修改下app.js
烦衣,結(jié)果我這里就不顯示了,跟上面那張圖是一樣的,更新的資源并沒有生效花吟,現(xiàn)在我們更新下manifest文件秸歧,比如把版本改為0.12
很顯然,只有更新了manifest文件衅澈,對(duì)離線資源的更新才能在瀏覽器上生效键菱。最后,我們來試試離線狀態(tài)下是什么情況今布,這才是離線存儲(chǔ)的重頭戲经备。通過Chrome設(shè)置離線狀態(tài),刷新頁(yè)面
由于在離線狀態(tài)部默,所以瀏覽器無法訪問到manifest文件侵蒙,但是網(wǎng)頁(yè)還是可以正常訪問,這就是離線存儲(chǔ)的威力傅蹂。
對(duì)于HTML5中離線存儲(chǔ)對(duì)象window.applicationCache
有幾個(gè)事件需要我們關(guān)注下:
1.oncached
:當(dāng)離線資源存儲(chǔ)完成之后觸發(fā)這個(gè)事件纷闺,這個(gè)是文檔的說法,我在Chrome上面測(cè)試的時(shí)候并沒有觸發(fā)這個(gè)事件份蝴。
2.onchecking
:當(dāng)瀏覽器對(duì)離線存儲(chǔ)資源進(jìn)行更新檢查的時(shí)候會(huì)觸發(fā)這個(gè)事件
3.ondownloading
:當(dāng)瀏覽器開始下載離線資源的時(shí)候會(huì)觸發(fā)這個(gè)事件
4.onprogress
:當(dāng)瀏覽器在下載每一個(gè)資源的時(shí)候會(huì)觸發(fā)這個(gè)事件急但,每下載一個(gè)資源就會(huì)觸發(fā)一次。
5.onupdateready
:當(dāng)瀏覽器對(duì)離線資源更新完成之后會(huì)觸發(fā)這個(gè)事件
6.onnoupdate
:當(dāng)瀏覽器檢查更新之后發(fā)現(xiàn)沒有資源更新的時(shí)候觸發(fā)這個(gè)事件