霍冰鵬
(晉城職業(yè)技術(shù)學(xué)院 信息中心,山西 晉城 048026)
隨著HTML5[1]技術(shù)發(fā)展迅速,在HTML 5平臺上,視頻、音頻、圖像、動畫以及同電腦的交互都被標(biāo)準(zhǔn)化。HTML功能越來越豐富,支持圖片上傳拖拽、支持Localstorage、支持 Web SQL Database、支持文件存儲Api等等。致力于將Web帶入一個更為成熟的應(yīng)用平臺,本文介紹HTML 5的離線緩存[2]Web應(yīng)用的功能。
離線存儲的三大核心功能作用:
離線資源緩存需要一種方式來指明應(yīng)用程序離線工作時所需的資源文件。這樣,瀏覽器才能在在線狀態(tài)時,把這些文件緩存到本地。此后,當(dāng)用戶離線訪問應(yīng)用程序時,這些資源文件會自動加載,從而讓用戶正常使用。HTML5中,通過Cache manifest文件指明需要緩存的資源,并支持自動和手動兩種緩存[3]更新方式。
在線狀態(tài)檢測:開發(fā)者需要知道瀏覽器是否在線,這樣才能夠針對在線或離線的狀態(tài),做出對應(yīng)的處理。在HTML5中,提供了兩種檢測當(dāng)前網(wǎng)絡(luò)是否在線的方式。
本地數(shù)據(jù)存儲:離線時,需要能夠把數(shù)據(jù)存儲到本地,以便在線時同步到服務(wù)器上。為了滿足不同的存儲需求,HTML5提供了DOM Storage和Web SQL Database兩種存儲機(jī)制[4][5]。前者提供了易用的key/value對存儲方式,而后者提供了基本的關(guān)系數(shù)據(jù)庫存儲功能。
(1)在html標(biāo)簽里通過manifest屬性引用一個cache.manifest文件,該文件里聲明了瀏覽器需緩存的所有資源文件,如下所示:
(2)關(guān)于cache.manifest的定義
CACHE MANIFEST
# 注釋:需要緩存的文件,無論在線與否,均從緩存里讀取
chched.js
cached.css
# 注釋:不緩存的文件,無論緩存中存在與否,均重新獲取
NETWORK:
uncached.js
uncached.css
# 注釋:獲取不到資源時的備選路徑,如index.html訪問失敗,則返回404頁面
FALLBACK:
index.html 404.html
幾個需要關(guān)注的細(xì)節(jié)
cache.manifest文件的 MIME類型是text/cache-manifest,至于如何讓web服務(wù)器返回.manifest文件時添加 Content-Type:text/cache-manifest,不同服務(wù)器配置細(xì)節(jié)不同,此處不展開。
cache.manifest寫法以CACHE MANIFEST開頭,文件編碼格式必須是utf-8。
歸納起來,步驟如下:
配置服務(wù)器支持cache.manifest的Contenttype:manifest
編寫cache.manifest文件
html頁面引用cache.manifest文件
瀏覽器通過window.applicationCache對象來及其相應(yīng)屬性、接口、事件供用戶構(gòu)建離線應(yīng)用,詳細(xì)可見applicationCache
//當(dāng)前文檔對應(yīng)的applicationCache對象
window.applicationCache
//當(dāng)前緩存所處的狀態(tài),為0~5的整數(shù)值,分別對應(yīng)一個狀態(tài),并分別對應(yīng)一個常量
window.applicationCache.status
window.applicationCache.UNCACHED ===0//未緩存,比如一個頁面沒有制定緩存清單,其狀態(tài)就是UNCACHED
window.applicationCache.IDLE === 1//空閑,緩存清單指定的文件已經(jīng)全部被頁面緩存,此時狀態(tài)就是IDLE
window.applicationCache.CHECKING = ==2//頁面正在檢查當(dāng)前離線緩存是否需要更新
window.applicationCache.DOWNLOADING===3//頁面正在下載需要更新的緩存文件
window.applicationCache.UPDATEREADY===4//頁面緩存更新完畢
window.applicationCache.OBSOLETE = ==5//緩存過期,比如頁面檢查緩存是否過期時,發(fā)現(xiàn)服務(wù)器上的.manifest文件被刪掉了
//常用API,在后面會稍詳細(xì)介紹
window.applicationCache.update()//update方法調(diào)用時,頁面會主動與服務(wù)器通信,檢查頁面當(dāng)前的緩存是否為最新的,如不是,則下載更新后的資源
window.applicationCache.swapCache()//updateready后,更新到最新的應(yīng)用緩存
除了上面提及的屬性、接口外,window.applicationCache還包含了一系列的事件,大部分與上面提到的 window.applicationCache.status對應(yīng),如下表:
事件名 關(guān)聯(lián)屬性 事件釋義onchecking CHECKING 見上文對關(guān)聯(lián)屬性的解釋ondownloading DOWNLOADING onupdateready UPDATEREADY onobsolete OBSOLETE oncached IDLE更新出錯,如檢查更新時.manifest被人誤刪了onnoupdate 檢查后,發(fā)現(xiàn)緩存無需更新onprog onerror ress -
假設(shè)我們第一次在chrome里面訪http://localhost/html5/has_cache/cache.html,如下所示:
打開控制臺,看到如下:
由上到下依次為(cache= window.applicationCache):檢查是否需要下載/更新緩存,cache.status===cache.CHECKING
發(fā)現(xiàn)本地還沒有緩存文件,開始下載,cache.status===cache.DOWNLOADING正在下載緩存文件,cache.staus===cache.PROGRESS,下載完畢,并緩存在本地,cache.status===cache.CACHED。
再次訪問http://localhost/blog/html5/cache/has_cache/cache.html
假設(shè).manifest沒有變化,打開控制臺,如下所示:
由上到下依次為:
1)檢查是否需要下載/更新緩存,cache.status===cache.CHECKING發(fā)現(xiàn)服務(wù)器上沒有更新,cache.status===cahce.NOUPDATE。
2)假設(shè)cache.manifest已經(jīng)發(fā)生變化,則如下截圖所示:
(1)本地手動刪除,各瀏覽器實現(xiàn)方式不同。以chrome為例,輸入chrome://appcache-internals/,可以查看本地的離線緩存,也可以進(jìn)行刪除。
(2)更新.manifest文件,瀏覽器檢測到.manifest變更后,會主動更新本地緩存。(需要注意的是,假如沒有更新.manifest,即使你對緩存清單里的文件進(jìn)行了修改,瀏覽器依舊會頑強(qiáng)地從本地緩存里面讀取修改之前的文件)。
(3)通過applicationCache對象的API來主動更新,主要涉及接口為update()以及swapCache()。
cache.update(),說明:啟動應(yīng)用緩存下載進(jìn)程,由于瀏覽器通常會主動檢查.manifest文件確認(rèn)緩存是否需要更新,所以大部分情況下這個方法是沒必要的。但對于一些可能在瀏覽器里待上長達(dá)一個星期左右的應(yīng)用,比如電子郵箱,這個方法就會派上用場,比如每隔1天檢查下本地緩存的一些文件在服務(wù)器上是否已經(jīng)更新。
cache.swapCache(),說明:如果瀏覽器已經(jīng)更新了新的離線緩存,則切到最新的緩存去。對于已經(jīng)加載解析的資源,如CSS、圖片等,并不會導(dǎo)致其重新加載、解析一遍。唯一的變化就是,后續(xù)對緩存資源的請求,獲取到的都是本地的最新緩存。需要注意的是,swapCache方法需要在updateready事件觸發(fā)后調(diào)用。調(diào)用update方法,更新了本地緩存,但如果不調(diào)用swapCache方法,在本次會話中,重新請求已經(jīng)更新過的資源,還是拿到老的文件。
假設(shè)有cache.html、cache.manifest、cache.js,分別如下:
假設(shè)我們現(xiàn)在已經(jīng)打開瀏覽器訪問http://localhost/html5/cache/mod_cache/cache.html,在打開頁面5s左右后,有人修改了cache.js里變量改test的值,如下:var test=11;//最初為10,現(xiàn)在修改為11,同時修改了cache.manifest文件(隨便在注釋里添加幾個數(shù)字即可)。之前已經(jīng)設(shè)置了20s后,調(diào)用update方法檢查緩存資源是否更新,此時瀏覽器發(fā)現(xiàn)cache.manifest文件發(fā)生變化,且cache.js的確被修改的,于是更新了本地緩存。
在cache.html里面,將cache.swapCache()這句注釋掉了,是否將這句注釋掉,是否有差別?差別在哪里?直接看結(jié)果:
(1)無cache.swapCache(),輸出結(jié)果:test:10
(2)有cache.swapCache(),輸出結(jié)果:test:11
結(jié)合API說明不難想到兩者之間的差別,當(dāng)沒有調(diào)用cache.swapCache()時候,即使重新請求cache.js,加載的還是緩存更新前的cache.js(老的緩存);若調(diào)用了cache.swapCache(),則重新請求cache.js時,加載的是已經(jīng)更新后的cache.js(最新的緩存)。
傳統(tǒng)的Web技術(shù)開發(fā)的應(yīng)用最致命的就是用戶體驗問題,頁面跳轉(zhuǎn)和過多的請求,大大影響了加載速度和用戶體驗。如果采用HTML5的離線儲存訪問Web應(yīng)用,對于用戶來說非常重要,用戶可以訪問本地的緩存文件,僅加載被修改過的離線資源,避免同一資源對服務(wù)器多次的請求,并且降低了對服務(wù)器的訪問壓力,提升了Web訪問速度。
[1]李燁民.基于HTML 5的前端本地化存儲技術(shù)[J].成都大學(xué)學(xué)報:2012,31(1):67-69.
[2]馬新強(qiáng),孫 兆,袁 哲.Web標(biāo)準(zhǔn)與HTML 5的核心技術(shù)研究[J].重慶文理學(xué)院學(xué)報,2010,29(6):61-64.
[3]黃 敏,張衛(wèi)東,李眾立.Web緩存技術(shù)的應(yīng)用與研究[J].計算機(jī)工程與設(shè)計,2003,24(5):33-35.
[4]歐少閩,龔明龍,朱凌楓,侯曉利,蔡偉鴻.基于HTML5的EX-DRM Web離線應(yīng)用系統(tǒng)[J].汕頭大學(xué)學(xué)報,2011,26(4):58-65.
[5]吳良波,金連甫.離線應(yīng)用本地數(shù)據(jù)存儲設(shè)計與實現(xiàn)[J].計算機(jī)工程與設(shè)計,2010,31(6):1236-1239.