HTML5 manifest離線快取

JouyPub發表於2019-02-16

一、基本概念

離線快取是HTML5新引入的技術,能夠讓你的Web應用程式指定哪些檔案可以快取在本地,使得你的網路斷開時依然可以通過本地的快取來進行訪問瀏覽。

二、使用方法

1. MIME type 宣告

首先,因為manifest檔案必須是一個MIME type為text/cache-manifest型別的存在。檔案字尾名可以自定義(建議為.appcache)所以我們需要現在服務端將.appcache字尾的檔案型別宣告為text/cache-manifest。以apache為例,我們需要在httpd.conf中加上:

AddType text/cache-manifest .appcache

2. 在HTML檔案中引入manifest檔案

<!-- clock.html -->
<!DOCTYPE html>
<html manifest="clock.appcache">

其中manifest檔案的字尾名必須為.appcache,並且和引入該manifest的頁面同源

3. manifest檔案語法

CACHE MANIFEST
# 上面這行是必須的

# 這是一行註釋
# 在這個檔案中的任何地方都可以新增
# 它們全部都會被忽略
  # 在註釋之前可以有空格
  # 但必須是在單行前

# 空行也會被忽略

# 這些列在最開始的檔案都是需要被快取的
# 或者是那些列在"CACHE:"裡的, "CACHE"頭必須寫在這些檔案之前,如同
# 下面寫好的那樣
images/sound-icon.png
images/background.png
# 注意,每個檔案必須單獨一行

# 線上白名單中出現的這個檔案,它不會被快取,並且,
# 對該檔案的引用,將繞過快取,總是會
# 從網路中獲取目標(或在使用者離線時,嘗試從網路上獲取)
NETWORK:
comm.cgi

# 這是另一塊要快取的檔案,這次只有一個css檔案
CACHE:
style/default.css

我們也可以書寫成這樣:

CACHE MANIFEST
#version 1.0
CACHE:
style/default.css
images/sound-icon.png
images/background.png
NETWORK:
*
  • CACHE MANIFEST:這個是必須的,並且一定要寫在manifest檔案開頭
  • CACHE:快取清單列表,此處列出的為需要進行離線快取的資原始檔
  • NETWORK: 白名單列表,需要與服務端進行互動獲取的資原始檔,此處必須列出除快取清單列表以外所有的資源地址(可以使用萬用字元*星號代替),否則沒有列出的資原始檔將載入失敗

引入manifest的頁面,即使沒有被列入快取清單中,仍然會被使用者代理快取。並且無法通過白名單列表去除。

(快取清單的檔案列表可以使用絕對路徑或絕對URL地址)

開啟離線快取後,我們可以在chrome中開啟f12來看看資源載入有啥區別

可以看出,使用離線快取後的資源,資源請求的狀態碼都變為200,並且在size欄中都被標明為(form cache),載入速度也是顯而易見的。

4. 快取如何更新?

資源被離線快取後,無論我們在後端如何更改資原始檔,客戶端都不會拉取到修改過的檔案。

原來,只有當manifest檔案被更新後(修改檔案任何地方,包括註釋等),客戶端才會更新離線快取檔案,並且每次都會更新全部的快取檔案,包括沒有被修改的資原始檔,但一般這些檔案都會走304的快取策略。

另外,在服務端修改manifest檔案後,客戶端第一次訪問頁面需要再重新整理一次才能獲取最新的資源。因為對於瀏覽器來說,manifest的載入是要晚於其他資源的. 這就導致check manifest的過程是滯後的。發現manifest改變,所有瀏覽器的實現都是緊隨這做靜默更新資源,以保證下次pv,應用到更新。(這一點很蛋疼,但還是有解決辦法,請繼續往下看)。

5. 離線快取物件和事件處理

在javascript中我們可以通過window.applicationCache來訪問快取物件,物件中包含了一個status屬性以及若干的待監聽的事件處理器。

其中status屬性代表的是當前離線應用的狀態,它可能的值為:

  • UNCACHED (0):未啟用離線應用
  • IDLE (1):已開啟離線應用,但本地快取的資源是最新的,並且未標記為廢棄資源
  • CHECKING (2):當前更新快取的狀態為“檢查中”
  • DOWNLOADING (3):當前更新快取的狀態為“下載資源中”
  • UPDATEREADY (4):當前更新快取的狀態為“更新完畢”
  • OBSOLETE (5):已開啟離線應用,但快取資源都已標記為廢棄

離線快取事件:

  1. checking:在第一次下載manifest檔案時,或者檢查是否需要更新時觸發
  2. noupdate:manifest檔案未修改,不需要下載新的快取檔案時觸發
  3. downloading:準備更新快取之前,或者第一次下載資源之前觸發
  4. progress:下載資源時觸發,每下載一個資源都會觸發一次
  5. cached:頁面首次啟用離線快取,並且離線快取下載完畢時觸發
  6. updateready:資源更新完畢時觸發
  7. obsolete:載入manifest檔案時遇到401或404錯誤時觸發
  8. errorEvent載入manifest檔案時遇到401或404錯誤時觸發

這樣,我們就可以通過updateready事件來讓離線快取更新後自動重新整理頁面了,雖然還是比較挫:

applicationCache.addEventListener(‘updateready’, function(){
       location.href=”test.html”;
}, false);

6. 離線快取的下線

要將離線快取下線,我們只需要將服務端的manifest檔案刪除即可,同時也要將HTML中的  manifest="manifest.appcache" 刪除(不刪也可以,會在console控制檯報錯,但不會影響頁面訪問),刪除後使用者再第一次訪問還是原來的快取頁面,還需要再重新整理一次。。。蛋疼吧。

相關文章