HTML5離線存儲 初探


本文主要內容歸納如下:

一、離線存儲的作用;

二、如何實現離線存儲;

三、applicationCache對象,及屬性、事件、接口

四、訪問緩存應用,相應觸發事件,及其對應狀態;

五、如何更新離線緩存

六、demo演示:update后是否調用swapCache的區別;

七、寫在后面 

一、離線存儲的作用

1、用戶可離線訪問你的應用,這對於無法隨時保持聯網狀態的移動終端用戶來說尤其重要

2、用戶訪問本地的緩存文件,通常意味着更快的訪問速度

3、僅僅加載被修改過的資源,避免同一資源對服務器多次的請求,大大降低了對服務器的訪問壓力 

二、如何實現離線存儲

1、在html標簽里通過manifest屬性引用一個cache.manifest文件,該文件里聲明了瀏覽器需緩存的所有資源文件,如下所示: 

<!DOCTYPE html>
<html lang='cn' manifest='cache.manifest'>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>離線緩存示例頁面</title>
<!-- CSS文件引用 -->
</head>

<body>
<!-- 各種標簽 -->
</body>

<!-- 各種腳本文件  -->
</html>

2、關於cache.manifest的定義

CACHE MANIFEST
# 注釋:需要緩存的文件,無論在線與否,均從緩存里讀取
chched.js
cached.css

# 注釋:不緩存的文件,無論緩存中存在與否,均從新獲取
NETWORK:
uncached.js
uncached.css

# 注釋:獲取不到資源時的備選路徑,如index.html訪問失敗,則返回404頁面
FALLBACK:
index.html 404.html

3、幾個需要關注的細節

  • cache.manifest 文件的MIME類型是text/cache-manifest,至於如何讓web服務器返回.manifest文件時添加 Content-Type: text/cache-manifest,不同服務器配置細節不同,此處不展開
  • cache.manifest寫法以CACHE MANIFEST開頭,文件編碼格式必須是utf-8
  • 引用cache.manifest的html文檔會被默認包含進緩存清單

4、歸納起來,步驟如下:

  • 配置服務器支持 cache.manifest 的Content-type: manifest
  • 編寫 cache.manifest 文件
  • html頁面引用cache.manifest文件

 

三、applicationCache對象,及屬性、事件、接口

瀏覽器通過window.applicationCache對象來及其相應屬性、接口、事件供用戶構建離線應用,詳細可見 applicationCache 

//當前文檔對應的applicationCache對象
window.applicationCache

//當前緩存所處的狀態,為0~5的整數值,分別對應一個狀態,並分別對應一個常量
window.applicationCache.status

window.applicationCache.UNCACHED === 0    //未緩存,比如一個頁面沒有制定緩存清單,其狀態就是UNCACHED
window.applicationCache.IDLE === 1 //空閑,緩存清單指定的文件已經全部被頁面緩存,此時狀態就是IDLE
window.applicationCache.CHECKING === 2 //頁面正在檢查當前離線緩存是否需要更新
window.applicationCache.DOWNLOADING === 3 //頁面正在下載需要更新的緩存文件
window.applicationCache.UPDATEREADY === 4  //頁面緩存更新完畢
window.applicationCache.OBSOLETE === 5  //緩存過期,比如頁面檢查緩存是否過期時,發現服務器上的.manifest文件被刪掉了

//常用API,在后面會稍詳細介紹
window.applicationCache.update()  //update方法調用時,頁面會主動與服務器通信,檢查頁面當前的緩存是否為最新的,如不是,則下載更新后的資源
window.applicationCache.swapCache()  //updateready后,更新到最新的應用緩存

除了上面提及的屬性、接口外,window.applicationCache還包含了一系列的事件,大部分與上面提到的 window.applicationCache.status對應,如下: 

事件名 關聯屬性 事件釋義
onchecking CHECKING 見上文對關聯屬性的解釋
ondownloading DOWNLOADING -
onupdateready UPDATEREADY -
onobsolete OBSOLETE -
oncached IDLE -
onerror   更新出錯,如檢查更新時.manifest被人誤刪了
onnoupdate   檢查后,發現緩存無需更新
onprogress   -

 

  

 

 

 

 

 

四、訪問緩存應用,相應觸發事件,及其對應狀態

1、假設我們在第一次在chrome里面訪問http://localhost/blog/html5/has_cache/cache.html,如下所示:

打開控制台,看到如下:

由上到下依次為(cache = window.applicationCache):

  1. 檢查是否需要下載/更新緩存,cache.status===cache.CHECKING
  2. 發現本地還沒有緩存文件,開始下載,cache.status===cache.DOWNLOADING
  3. 正在下載緩存文件,cache.staus===cache.PROGRESS
  4. 下載完畢,並緩存在本地,cache.status===cache.CACHED

2、再次訪問http://localhost/blog/html5/cache/has_cache/cache.html

1)假設.manifest沒有變化

打開控制台,如下所示:

由上到下依次為:

  1. 檢查是否需要下載/更新緩存,cache.status===cache.CHECKING
  2. 發現服務器上沒有更新,cache.status===cahce.NOUPDATE

2)假設cache.manifest已經發生變化,則如下截圖所示,不贅述:

 

五、如何更新離線緩存

1、本地手動刪除,各瀏覽器實現方式不同。以chrome為例,輸入chrome://appcache-internals/,可以查看本地的離線緩存,也可以進行刪除

2、更新.manifest文件,瀏覽器檢測到.manifest變更后,會主動更新本地緩存。(需要注意的是,假如沒有更新.manifest,即使你對緩存清單里的文件進行了修改,瀏覽器依舊會頑強地從本地緩存里面讀取修改之前的文件)

3、通過applicationCache對象的API來主動更新,主要涉及接口為update()以及swapCache()

cache.update()

官方說明:啟動應用緩存下載進程,由於瀏覽器通常會主動檢查.manifest文件確認緩存是否需要更新,所以大部分情況下這個方法是沒必要的。但對於一些可能在瀏覽器里待上長達一個星期左右的應用,比如電子郵箱,這個方法就會排上用場,比如每隔1天檢查下本地緩存的一些文件在服務器上是否已經更新。

個人理解:
cache.swapCache()

官方說明:如果瀏覽器已經更新了新的離線緩存,則切到最新的緩存去。對於已經加載解析的資源,如CSS、圖片等,並不會導致其重新加載、解析一遍。唯一的變化就是,后續對緩存資源的請求,獲取到的都是本地的最新緩存。需要注意的是,swapCache方法需要在updateready事件觸發后調用。

個人理解:調用update方法,更新了本地緩存,但如果不掉用swapCache方法,在本次會話中,重新請求已經更新過的資源,還是拿到老的文件。

 

、demo演示:update后是否調用swapCache的區別

假設有cache.html、cache.manifest、cache.js,分別如下:

cache.html
<!DOCTYPE html>
<html lang='cn' manifest='cache.manifest'>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>離線緩存</title>
</head>
<body></body>
<script type="text/javascript" src="cache.js"></script>
<script type="text/javascript">
var cache = window.applicationCache;
conso.log('test:' + test);  //cache.js定義的一個變量,初始值為10

function load(url, callback){
    var script = document.createElement('script');
    script.src = url;
    script.onload = function(){
        callback && callback();
    }
    document.body.appendChild(script);
}

setTimeout(function(){
    cache.addEventListener('updateready', function(){
        log('更新完畢');
        //cache.swapCache();
        load('cache.js', function(){
            log('test:' + test);    //test: 10
        });    
    });
    cache.update();

}, 20*1000);
</script>
</html>
cache.js
var test = 10;  //測試用變量
cache.manifest
CACHE MANIFEST
# Javascript v0
./cache.js

假設我們現在已經打開瀏覽器訪問http://localhost/blog/html5/cache/mod_cache/cache.html,在打開頁面5s左右后,有人修改了cache.js里變量改test的值,如下:

var test = 11;  //最初為10,現在修改為11

同時修改了cache.manifest文件(隨便在注釋里添加幾個數字即可)。之前已經設置了20s后,調用update方法檢查緩存資源是否更新,此時瀏覽器發現cache.manifest文件發生變化,且cache.js的確被修改的,於是毫不猶豫地更新了本地緩存。

CACHE MANIFEST
# Javascript v11111
./cache.js

在cache.html里面,將cache.swapCache()這句注釋掉了,是否將這句注釋掉,是否有差別?差別在哪里?直接看結果:

1、無cache.swapCache(),輸出結果:test: 10

2、有cache.swapCache(),輸出結果:test: 11

結合API說明不難想到兩者之間的差別,當沒有調用cache.swapCache()時候,即使重新請求cache.js,加載的還是緩存更新前的cache.js(老的緩存);若調用了cache.swapCache(),則重新請求cache.js時,加載的是已經更新后的cache.js(最新的緩存);

七、寫在后面

在離線存儲的實現方面,似乎不同瀏覽器理解也不同,最初在chrome下測試的同時,也在firefox下進行測試,然后,不忍心再對比着測試,就挑了據說實現比較靠譜的chrome接着往下測試

html5離線存儲還有很多有意思的東西尚待發掘。自己也是剛剛接觸,理解以及文章內容難免存在偏差之處,請諒解並指出。

 

參考資料:

http://i.wanz.im/2010/07/01/html5_offline_file_cache_guide_for_beginner/

http://www.whatwg.org/specs/web-apps/current-work/#applicationcache

《HTML5高級程序設計》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM