HTML5 Application Cache

1、應用場景

離線訪問對基於網絡的應用而言越來越重要。雖然所有瀏覽器都有緩存機制,但它們並不可靠,也不一定總能起到預期的作用。HTML5 使用ApplicationCache 接口解決了由離線帶來的部分難題。前提是你需要訪問的web頁面至少被在線訪問過一次。

2、使用緩存接口可爲您的應用帶來以下三個優勢:
離線瀏覽 – 用戶可在離線時瀏覽您的完整網站
速度 – 緩存資源爲本地資源,因此加載速度較快。
服務器負載更少 – 瀏覽器只會從發生了更改的服務器下載資源。
3、離線本地存儲和傳統的瀏覽器緩存有什麼不同呢?
離線存儲爲整個web提供服務,瀏覽器緩存只緩存單個頁面;
離線存儲可以指定需要緩存的文件和哪些文件只能在線瀏覽,瀏覽器緩存無法指定;
離線存儲可以動態通知用戶進行更新。
4、如何實現

離線存儲是通過manifest文件來管理的,需要服務器端的支持,不同的服務器開啓支持的方式也是不同的。對於Tomcat需要修改 /conf/web.xml文件,添加如下MIMEType配置:

 <mime-mapping>
        <extension>manifest</extension>
        <mime-type>text/cache-manifest</mime-type>
 </mime-mapping>
注意,<extension>manifest</extension>中內容必須和manifest文件後綴名一致。

一個典型的manifest文件應該類似這樣:

CACHE MANIFEST//必須以這個開頭
version 1.0 //最好定義版本,更新的時候只需修改版本號
CACHE:
    m.png
    test.js
    test.css
NETWORK:
    *
FALLBACK
    online.html offline.html
其中CACHE指定需要緩存的文件;NETWORK指定只有通過聯網才能瀏覽的文件,*代表除了在CACHE中的文件;FALLBACK每行分別指定在線和離線時使用的文件
要讓manifest管理存儲。

有了manifest文件後,還需要在html標籤中定義manifest屬性,如下:

<!DOCTYPE html>
<html lang="en" manifest='test.manifest'>
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
  
</body>
</html>
5、通過JS動態控制更新
應用在離線後將保持緩存狀態,除非發生以下某種情況:
用戶清除了瀏覽器對您網站的數據存儲。
清單文件經過修改。請注意:更新清單中列出的某個文件並不意味着瀏覽器會重新緩存該資源。清單文件本身必須進行更改。

緩存狀態:
window.applicationCache 對象是對瀏覽器的應用緩存的編程訪問方式。其 status 屬性可用於查看緩存的當前狀態:

var appCache = window.applicationCache;
switch (appCache.status) {
  case appCache.UNCACHED: // UNCACHED == 0
    return 'UNCACHED';
    break;
  case appCache.IDLE: // IDLE == 1
    return 'IDLE';
    break;
  case appCache.CHECKING: // CHECKING == 2
    return 'CHECKING';
    break;
  case appCache.DOWNLOADING: // DOWNLOADING == 3
    return 'DOWNLOADING';
    break;
  case appCache.UPDATEREADY:  // UPDATEREADY == 4
    return 'UPDATEREADY';
    break;
  case appCache.OBSOLETE: // OBSOLETE == 5
    return 'OBSOLETE';
    break;
  default:
    return 'UKNOWN CACHE STATUS';
    break;
};

要以編程方式更新緩存,請先調用 applicationCache.update()。此操作將嘗試更新用戶的緩存(前提是已更改清單文件)。最後,當applicationCache.status 處於 UPDATEREADY 狀態時,調用 applicationCache.swapCache() 即可將原緩存換成新緩存。

var appCache = window.applicationCache;
appCache.update(); // Attempt to update the user's cache.
...
if (appCache.status == window.applicationCache.UPDATEREADY) {
  appCache.swapCache();  // The fetch was successful, swap in the new cache.
}

請注意:以這種方式使用 update() 和 swapCache() 不會向用戶提供更新的資源。此流程只是讓瀏覽器檢查是否有新的清單、下載指定的更新內容以及重新填充應用緩存。因此,還需要對網頁進行兩次重新加載才能向用戶提供新的內容,其中第一次是獲得新的應用緩存,第二次是刷新網頁內容。

好消息是,您可以避免重新加載兩次的麻煩。要使用戶更新到最新版網站,可設置監聽器,以監聽網頁加載時的 updateready 事件:
//Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
  window.applicationCache.addEventListener('updateready', function(e) {
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // Browser downloaded a new app cache.
      // Swap it in and reload the page to get the new hotness.
      window.applicationCache.swapCache();
      if (confirm('A new version of this site is available. Load it?')) {
        window.location.reload();
      }
    } else {
      // Manifest didn't changed. Nothing new to server.
    }
  }, false);
}, false);

6、APPCACHE 事件(詳見W3C Spec:http://www.w3.org/TR/2012/WD-html5-20120329/offline.html#offline

Event name Interface Fired when... Next events
checking Event The user agent is checking for an update, or attempting to download the manifest for the first time. This is always the first event in the sequence. noupdatedownloading,obsoleteerror
noupdate Event The manifest hadn't changed. Last event in sequence.
downloading Event The user agent has found an update and is fetching it, or is downloading the resources listed by the manifest for the first time. progresserrorcached,updateready
progress ProgressEvent The user agent is downloading resources listed by the manifest. progresserrorcached,updateready
cached Event The resources listed in the manifest have been downloaded, and the application is now cached. Last event in sequence.
updateready Event The resources listed in the manifest have been newly redownloaded, and the script can use swapCache() to switch to the new cache. Last event in sequence.
obsolete Event The manifest was found to have become a 404 or 410 page, so the application cache is being deleted. Last event in sequence.
error Event The manifest was a 404 or 410 page, so the attempt to cache the application has been aborted. Last event in sequence.
The manifest hadn't changed, but the page referencing the manifest failed to download properly.
A fatal error occurred while fetching the resources listed in the manifest.
The manifest changed while the update was being run. The user agent will try fetching the files again momentarily.
通過對這些事件的監聽處理能更好的控制應用程序文件的緩存、更新。

7.一個簡單的離線緩存的應用
建一個web工程AppCache,包括四個文件:
appcache_offline.html

<html manifest="clock.manifest">
  <head>
    <title>AppCache Test</title>
    <link rel="stylesheet" href="clock.css">
    <script src="clock.js"></script>
  </head>
  <body>
    <p><output id="clock"></output></p>
    <div id="log"></div>
  </body>
</html>
clock.manifest
CACHE MANIFEST
#VERSION 1.0
CACHE:
clock.css
clock.js
clock.css
output { font: 2em sans-serif; }
clock.js
setTimeout(function () {
    document.getElementById('clock').value = new Date();
}, 1000);
聯網情況下訪問:http://localhost:8080/AppCache/appcache_offline.html,頁面間斷顯示系統當前時間;斷開網絡後仍然可以正常訪問。如下所示:

Wed Oct 17 2012 18:34:41 GMT+0800 (CST)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章