天天看點

html5的離線存儲問題彙總

  HTML5的一個重要特性就是離線存儲,所謂的離線存儲就是将一些資源檔案儲存在本地,這樣後續的頁面重新加載将使用本地資源檔案,在離線情況下可以繼續通路web應用,同時通過一定的手法(更新相關檔案或者使用相關API),可以更新、删除離線存儲等操作;

       HTML5的離線存儲使用一個manifest檔案來标明哪些檔案是需要被存儲的,使用如 <html manifest='offline.manifest'> 來引入一個manifest檔案,這個檔案的路徑可以是相對的,也可以是絕對的,如果你的web應用很多,而且希望能集中管理manifest檔案,那麼靜态檔案伺服器是個不錯的選擇。

       對于manifest檔案,要求:檔案的mime-type必須是 text/cache-manifest類型。如果你是JAVA工程,在你的web.xml中配置請求字尾為manifest的格式:

  1. <mime-mapping>
  2.         <extension>manifest</extension>
  3.         <mime-type>text/cache-manifest</mime-type>
  4. </mime-mapping>  

複制代碼

       這樣可以控制請求到的manifest檔案格式為text/cache-manifest的。

manifest檔案的格式:

  1. CACHE MANIFEST# 這一句必須存在,而且必須放在頭部# 指明緩存入口CACHE:index.htmlstyle.cssimages/logo.pngscripts/main.js# 以下資源必須線上通路NETWORK:login.php# 如果index.php無法通路則用404.html代替FALLBACK:/index.php /404.html

複制代碼        其中 CACHE 不是必須存在的,可以直接在 CACHE MANIFEST 行之下直接寫需要緩存的檔案,在這裡指明的檔案将被緩存到浏覽器本地。在NETWORK之下指明的檔案,是強制必須通過網絡資源擷取的,在FALLBACK下指明的是一種失敗的回調方案,比如上述index.php無法通路,那麼就發出404.htm請求

       這樣幾步就可以完成對離線存儲的支援。接下來要思考的,是如何更新離線存儲?

       當使用者本地再次聯網的時候,本地的離線存儲資源需要檢查是否需要更新,這個更新過程,也是通過manifest的更新來控制的,更新了manifest檔案,浏覽器會自動的重新下載下傳新的manifest檔案并在下一次重新整理頁面的時候進行資源檔案的重新請求(第三次重新整理替換本地緩存為最新緩存),而且這個請求是全局性的,也就是所有在manifest緩存清單中的檔案都會被請求一次,而不是單獨請求某個特定修改過的資源檔案,因為manifest是不知道哪個檔案被修改過了的。

       對于全局更新的擔心是不必要的,因為對于沒有更新過的資源檔案,請求依舊是304響應,隻有真正更新過的資源檔案才是200.

       是以控制離線存儲的更新,需要2個步驟,一是更新資源檔案,二是更新manifest檔案,特别的,更新manifest檔案是不需要修改什麼特定内容的,隻要是這個檔案随意一處被修改,那麼浏覽器就會感覺,對于我們的資源檔案通常名稱是固定的,比如**.css,更新内容不會帶有檔案名更新的情況下,需要更新manifest檔案怎麼操作呢?一個比較好的方式是更新任意一處# 開頭的注釋即可,其目的隻是告訴浏覽器這個manifest檔案被更新過。

       以上的這些内容,其更新操作都是浏覽器自動完成的。同樣的,W3C定義了離線存儲的API規範:http://www.whatwg.org/specs/web- ... k/#applicationcache

       提供了如下API:

  1. // 更新,一般來說更新下載下傳是通過使用者**(如浏覽器)自動完成的,但是這個方法适用于一些長期打開的頁面,比如郵件系統,可能這個頁面是長期打開的,而不會有重新整理動作,是以這個就比較适合做自動更新下載下傳
  2. void update();
  3. // 取消 
  4. void abort();
  5. // 替換緩存内容 ,對于manifest檔案的改變,通常是下一次的重新整理才會觸發下載下傳更新,第三次重新整理才會切換使用新的緩存檔案,通過這個方法,可以強制将緩存替換
  6. void swapCache();

複制代碼

提供了如下的事件:

  1. Event handler             Event handler event type
  2. onchecking             checking
  3. onerror                     error
  4. onnoupdate             noupdate
  5. ondownloading             downloading
  6. onprogress             progress
  7. onupdateready             updateready
  8. oncached                     cached
  9. onobsolete             obsolete

複制代碼

       最後說一個對于manifest比較特别的地方:對于某個檔案a.htm,其中有 <html manifest='a.manifest'> ,那麼離線存儲中,會自動将a.htm加入到清單中,這意味着a.htm的再次重新整理将從本地緩存中擷取,這樣的機制從官方得到的答複是“特别的設計”,而對我們來說,這種強加的特性在後續的開發過程中會有不少問題。

比如:

       1、如何計算PV UV,由于目前頁面被強制加入manifest,那麼PV 和UV的統計,成了一個難題,因為請求不再是發送到伺服器;

       2、對于某個使用manifest的檔案,其帶有的參數可能是随機性的統計參數,如sid=123sss, sid=234fff ,尤其是比如商品詳情的id字段等,這樣每個頁面都自動加入到manifest中,将會帶來很大的存儲開銷,而且是毫無意義的;

       是以伴随而來的,是如何在現有的體系架構下進行資料統計的難題,一個正常的方案是進入離線存儲頁面後自動發出ajax請求,以告知伺服器統計PV UV;

       對于第二個問題,可能就比較棘手,但是将GET請求的方式改成POST的方式确實是個解決問題的方案。

繼續閱讀