使用 jQuery Mobile 與 HTML5 開發 Web App —— HTML5 離線緩衝

來源:互聯網
上載者:User

標籤:

本文要介紹的,是 HTML5 離線網路應用程式的特性,離線網路應用程式在 W3C 中的實際名稱是 "Offline Web applications" ,也稱離線緩衝。當使用者開啟瀏覽器時,瀏覽器會將一個列表中指定的資源都下載並儲存在本地。下次當使用者再訪問這個網路程式時,瀏覽器會自動引用本機快取中相應的檔案,而不會再從網路下載這些資源。不管離線網路應用程式是否專為 Web Apps 而設,但這對於 Web Apps 來說無疑是個非常實用的特性,它使到 Web Apps 相對於原生 Apps 的一個重要劣勢 —— 高度依賴網路,得以大大減緩。開發人員可以利用這個特性把 Web Apps 中的元素緩衝到本地端,使到 Web Apps 可以離線工作,即使是需要連網工作的 Apps ,也可以緩衝部分檔案到本地端,減少頻寬佔用,這樣 Web Apps 相對於原生 Apps 就更加具有優勢了。下面正式開始介紹這個特性。

一. 離線網路應用程式基底礎

離線網路應用程式的核心是一個 content type (內容類型) 為 cache-manifest 的文字檔。這個檔案儲存了應用程式中需要離線儲存的檔案(HTML, CSS, JavaScript, 圖片等)。舉一個簡單的例子,若一個應用程式由以下檔案組成:

  • index.html
  • demo.css
  • demo.js
  • logo.png

index.html 為首頁,其他檔案是首頁中引用的資源,如果我們需要離線緩衝這個應用程式,需要在 index.html 的同級目錄下增加一個 manifest 檔案,並命名為 .manifest 尾碼檔案,而檔案中的內容可以這樣編寫:

12345 CACHE MANIFEST./index.html./demo.css./demo.js./logo.png

可以看出,以上檔案的路徑是相對路徑,這裡是相對於 manifest 檔案而言的。當然,你也可以使用絕對路徑,這並不影響 manifest 的使用。

manifest 檔案的編寫很簡單,但啟用離線緩衝還需一些步驟。首先是需要把 manifest 檔案和應用程式關聯起來,即把頁面指向緩衝名單,方法是為 html 標籤指定 manifest 值,例如:

1 <html manifest="demo.manifest">

其中 demo.manifest 是例子中編寫的 manifest 列表檔案。

小提示:若應用程式中有多個頁面,則每個頁面都需要與 manifest 關聯起來。

接著,開發人員必須給 manifest 檔案指定 text/cache-manifest 內容類型,這樣瀏覽器才能識別它。關於具體的方法,如果你的伺服器支援 .htaccess ,可以在 .htaccess 中寫入以下語句:

1 AddType text/cache-manifest .manifest

這樣做可以把 text/cache-manifest 的 MIME 類型和 .manifest 檔案關聯起來。當然,可能開發人員並沒有 .htaccess 的編寫入權限,但實際上,開發人員可以使用另外一些更實用的方法達到目的。因為在實際的項目開發中,應用程式中的檔案數量不會只像上例中僅有的 4 個,如果有很多的檔案需要緩衝,每個檔案都需要手動寫入 manifest 檔案實在比較費時,更麻煩的是,每次改動這些檔案都必須相應地改動 manifest 檔案,因此 Kayo 更加建議開發人員使用後台指令碼直接擷取需要緩衝的檔案並寫入一個 manifest 列表,Kayo 熟悉的後台指令碼是 PHP ,在 PHP 中,可以直接在代碼中設定 MIME 類型,這樣就不需要配置 Web 服務來完成對 manifest 的支援了。至於具體如何使用 PHP 編寫 manifest ,會在下面詳細介紹。

二. 瀏覽器支援

關於離線網路應用程式在現代瀏覽器中都已經實現完整的支援,IE 則完全不支援。具體如下:

Chrome 4+ , Firefox 3.5+ , Safari 4+ 和 Opera 10.6+

三. 白名單

預設情況下,開發人員會為應用程式中所有檔案指定緩衝,但實際上,仍有一些資源可能需要強製取消緩衝,即必須訪問網路資源,離線時該資源不可用。為元素強製取消緩衝可以在 manifest 檔案中使用關鍵字 NETWORK: 。在 NETWORK: 關鍵字下添加檔案的列表,這些檔案會強製取消緩衝,而這個檔案清單就稱為白名單 (Whitelist) 。實際上,對於需要緩衝的資源也是有關鍵字的,這個關鍵字是 EXPLICIT: ,但所有資源清單的開頭如果沒有添加關鍵字,預設都會被認為在 EXPLICIT: 關鍵字的列表下,因此需要緩衝的資源清單開頭可以忽略不寫關鍵字(如上例)。

例如,對上例進行擴充,把 logo.png 添加到白名單,可以這樣編寫 manifest 檔案。

1234567 CACHE MANIFEST./index.html./demo.css./demo.js NETWORK:./logo.png
四. 備選名單

備選名單是對於白名單的補充,在白名單中,沒有連網時,資源不能載入,這樣會導致頁面出現錯誤,如上例中,"logo.png" 被設定為白名單,如果使用者離線瀏覽該應用程式,會出現一個損壞的圖片連結,為了避免這種情況,可以使用 FALLBACK: 指定一個備選名單,備選名單中需要為一個資源準備兩個檔案,若能正常連網,會引用第一個檔案,離線時則引用第二個檔案,關於這個特點,有一個很實用的應用 —— 表明程式是離線工作還是連網工作,在不同的狀態下引用不同的圖片即可方便地表明狀態。接下來 Kayo 繼續擴充上例,為 logo.png 指定一個離線時的替換圖片 backup.png 。

1234567 CACHE MANIFEST./index.html./demo.css./demo.js FALLBACK:./logo.png ./backup.png
五. 更新 manifest

似乎,經過上面三個步驟後,應用程式的離線緩衝已經很好的工作了。但有一個很重要的問題仍需注意 —— 根據離線緩衝的工作原理,當使用者第一次使用應用程式時,瀏覽器會根據 manifest 檔案裡的列表下載指定的資源,在下次使用該應用程式時,瀏覽器會自動載入這些資源的副本,那麼假如開發人員修改了程式,瀏覽器仍舊會載入本地的資源,因此我們需要給瀏覽器一個提示,程式已經更新。

那麼什麼時候瀏覽器會更新本機快取呢?

只有當 manifest 修改後瀏覽器才會重新下載 manifest 中所有指定需要離線緩衝的檔案。而檢測 manifest 是否修改過是對 manifest 檔案的內容逐個字元進行比較,包括注釋和空行。當然,大多情況下,修改程式時並不會影響主要的檔案,所以 manifest 中的檔案清單也不會有改動,因此需要改動 manifest 以通知瀏覽器程式已更新的最好辦法是修改注釋,開發人員可以在 manifest 檔案中添加一行注釋,比如說是程式的版本號碼,當程式更新後同時修改 manifest 檔案中這個版本號碼,瀏覽器就會判定程式已經更新,自動重新下載所有需要離線緩衝的資源。例如,把上例改成:

12345678 CACHE MANIFEST# version 1.0./index.html./demo.css./demo.js FALLBACK:./logo.png ./backup.png

需要注意的是,"CACHE MANIFEST"是必要行,並且必須在 manifest 檔案中的第一行。這樣下次更改程式後同時修改 manifest 的程式版本號碼,瀏覽器就可以判定程式更新了。

手動更新緩衝

當然,為了能更精確地控製程序更新,最好是使用手動方法更新緩衝,離線網路應用程式規範中也提供了相應的手動更新緩衝的方法。開發人員可以使用 window.applicationCache.update() 方法手動更新緩衝,為了更準確地判斷是否需要更新,開發人員可以先檢測 window.applicationCache.status 的值,若其值為 "UPDATEREADY" (即瀏覽器檢測到 manifest 已被修改), 可以調用 window.applicationCache.update() 方法更新緩衝。例如:

123 if ( window.applicationCache.status == window.applicationCache.UPDATEREADY ){    window.applicationCache.update();}
六. 使用 PHP 指令碼編寫 manifest 檔案

如上面所說,使用指令碼編寫 manifest 檔案可以同時解決 manifest 副檔名與 MIME 類型關聯起來,還可以自動列出快取檔案。具體的編寫如下:

123456789101112131415161718192021222324 header(‘Content-Type: text/cache-manifest‘);echo "CACHE MANIFEST\n"; $allHashes = ""; // 建立一個字串儲存檔案的 md5 值 $dir = new RecursiveDirectoryIterator(".");foreach(new RecursiveIteratorIterator($dir) as $file){ // 擷取目前的目錄並遍曆檔案    if( $file->IsFile() && // 判斷擷取內容為檔案        $file->getFilename() != "manifest.php" && // "manifest.php" 不緩衝        $file->getFilename() != "logo.png" && // 備選資源不緩衝        $file->getFilename() != "offline.png" &&        !strpos( $file, ‘/.‘ ) &&        substr( $file->getFilename(), 0, 1 ) != "."){         echo "./" . $file->getFilename() . "\n";        $allHashes .= md5_file($file); // 把每一個緩衝的檔案的 md5 值串連起來    }  }  echo "FALLBACK:\n"; // 輸出備選名單echo "./logo.png ./offline.png\n"; echo "# " . md5($allHases) ."\n"; // 把串連起來的 md5 值重新計算一個 md5(因為串連所得的字串過於冗長)

在這個指令碼中,擷取了應用程式的目錄並把目錄中的檔案逐個添加到緩衝列表,同時在這個過程中排除如 "manifest.php" 和備選資源等檔案,並且,對每一個緩衝的檔案計算 md5 值,把這些值串連起來後重新計算一個 md5 並輸出到一行注釋中,這樣緩衝的檔案只要有一個發生了改變,都會影響這行注釋,從而使到整個 manifest 檔案發生改變,這樣就並不需要在更新程式後手動修改 manifest 檔案。可以看出,如果需要緩衝的檔案很多時,該方法將會十分方便,並且更新程式後 manifest 檔案也會被自動修改。當然,這隻是使用指令碼編寫 manifest 的其中一種方式,開發人員應視具體情況而制定相應的指令碼。

七. 關於離線網路應用程式的屬性、方法和事件

在 “手動更新緩衝” 中,Kayo 提到了一個對象 window.applicationCache ,這個對象中包含了與離線網路應用程式相關的屬性、方法和事件,除了上面涉及到的 status 屬性和 update() 方法外,還有其他的相關內容,下面開始對它們進行詳細介紹。

1. 屬性

window.applicationCache 對象中具有一個屬性 status ,該狀態會根據當前的緩衝狀態顯示不同的值和狀態編號,具體的屬性值如下:

  • UNCACHED 未開始緩衝狀態。 狀態編號:0
  • IDLE 空閉狀態。 狀態編號:1
  • CHECKING 正在檢查 manifest 檔案是否存在。 狀態編號:2
  • DOWNLOADING 正在下載快取檔案。 狀態編號:3
  • UPDATEREADY 更新下載已完成,等待更新狀態。 狀態編號:4
  • OBSOLETE 廢棄狀態。 狀態編號:5
2. 方法

接著,是相關的方法,具體如下:

  • update() 檢測與文檔關聯的 manifest 檔案是否有修改,如果有修改,則更新緩衝。若 manifest 檔案不存在或該緩衝已廢棄,則會拋出一個 InvalidStateError 錯誤。
  • abort() user agent 會發出一個訊號給當前的緩衝對象,中止應用緩衝的下載,如果頁面沒有使用離線網路應用程式,那麼在嘗試發出訊號後該方法不會再執行任何操作。
  • swapCache() 手動執行本機快取更新,並且只能在 updataReady 事件觸發時在事件回呼函數中調用。但需要注意該方法不會立即更新快取檔案,仍需要重新整理頁面才生效。若文檔關聯的 manifest 文檔不存在,會拋出一個 InvalidStateError 錯誤。
3. 事件

除了屬性和方法,window.applicationCache 對象還會根據一些情況在其身上觸發一些事件,開發人員應該瞭解這些事件,根據所觸發的事件,可以瞭解一個正在運作的離線緩衝的工作情況,然後根據不同的情況作出適當的處理。

  • checking 瀏覽器在檢測到 html 標籤上有 manifest 屬性後,會檢查相關聯的 manifest 檔案是否存在,同時觸發 checking 事件。
  • noupdate 在檢測到 manifest 沒有更新(即沒有修改)時觸發。
  • downloading 緩衝下載時觸發。
  • progress 下載進度(階段性事件)。
  • cached 已根據 manifest 檔案中指定的要求下載相應的資源。
  • updateready 更新時,已根據 manifest 檔案中指定的要求重新下載相應的資源。
  • obsolete manifest 檔案請求發生 404 或 410 錯誤時觸發,發生此事件表明該緩衝已被刪除。
  • error 以下四種情況都會觸發 error 事件:1. manifest 檔案請求發生 404 或 410 錯誤; 2. manifest 檔案沒有修改,但頁面無法正確引用 manifest ;3. 根據 manifest 檔案更新資源時發生致命錯誤(如上面提到的 InvalidStateError 錯誤);4. 當資源正在更新時 manifest 檔案被修改。

這裡 Kayo 需要指出一點,以上這些事件並不會在一個緩衝過程中全部觸發,如 error(前三種情況) , updateready , obsolete , noupdate , cached 均為一個緩衝過程中的最終事件,在一次緩衝過程中只會出現其中一個。又如 cached 事件,必須要有下載資源並且在完成後才觸發,即第二次開啟頁面並且 manifest 沒有修改是不會觸發 cached 事件(沒有下載資源),開發人員應仔細注意每個事件的觸發時刻,判斷在不同情況下應該利用何種事件。

這個例舉一個例子,使用 addEventListener 監聽 cached 事件,檢測到 cached 事件發生時彈出提示,即代表離線資源已經下載完成。

1234567 if(window.applicationCache) {     window.applicationCache.addEventListener(‘cached‘, function(){        alert(‘cached‘);    }, true); }
八. 完整執行個體 Demo

為了使讀者更好的理解離線網路應用程式的具體使用,這裡會把上面逐步擴充的例子寫成完整 Demo (為了簡化例子結構,這裡只使用 addEventListener 監聽事件,請使用 Chrome, Firefox 等現代瀏覽器瀏覽 Demo )。

完整 Demo 。

本文由 Kayo Lee 發表,本文連結:http://kayosite.com/web-app-by-jquery-mobile-and-html5-offline-web-applications.html

使用 jQuery Mobile 與 HTML5 開發 Web App —— HTML5 離線緩衝

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.