HTML5離線應用與客戶端存儲

序言

本篇文章會詳細介紹使用HTML5開發離線應用的步驟,以及本地存儲與cookie的一些異同,最後利用上面所學例子來實現一個購物車場景。css

使用HTML5離線存儲的基本過程以下:html

  1. 離線檢測:首先要對設備進行離線狀態檢測,根據設備在線或者離線判斷接下來的操做;html5

  2. 離線緩存:將須要被緩存的資源寫在一個描述文件(cache manifest)裏,當設備在線時進行緩存,以便用戶在離線時能夠正常使用;git

  3. 本地存儲:離線時,把必要的數據存儲到本地,當設備上線時將數據存儲到服務器上。github

下面就從這三個方面展開進行介紹。web

 

離線檢測

開發離線應用首先要檢測設備的狀態,根據設備在線或者離線進行接下來的操做。HTML5爲咱們提供了兩種判斷設備在線狀態的方式:屬性navigator.onLine和事件online/offline。編程

爲了檢測應用是否離線,咱們能夠經過navigator.onLine判斷設備的初始狀態,同時經過online/offline事件來肯定網絡的鏈接狀態是否變化。online/offline事件首先在body上觸發,隨後會沿着document.body, document, window的順序冒泡,因此咱們能夠對它們進行監聽得到設備的狀態變化。瀏覽器

if(navigator.onLine){
  //正常工做
}
else{
  //執行離線事件處理程序
}

window.addEventListener('online', function(){
  //進行離線緩存
});
window.addEventListener('offline', function(){
  //使用離線緩存
})

 

離線緩存

描述清單

經過離線檢測,咱們須要在設備在線時對須要的文件進行緩存。HTML5 的應用緩存(application cache),或者簡稱爲appcache,是專門爲開發離線Web應用而設計的。Appcache 就是從瀏覽器的緩存中分出來的一塊緩存區。要想在這個緩存中保存數據,可使用一個描述文件(manifest file),列出要下載和緩存的資源。下面是一個簡單的描述文件示例。緩存

CACHE MANIFEST
#上面的聲明必不可少

index.html
common.css

NETWORK:
*.html

CACHE:
login.html

FALLBACK:
*.html offline.html
/project /offline/project

描述文件的基本格式以下:安全

  1. CACHE MANIFEST書寫在第一行,並且必不可少;
  2. #開頭表明註釋;
  3. CACHE標識符:這是條目的默認部分。系統會在首次下載此標頭下列出的文件(或緊跟在CACHE MANIFEST 後的文件)後顯式緩存這些文件;
  4. NETWORK標識符:表明「白名單」,它表示的是不管在線離線都須要聯網訪問的文件;
  5. FALLBACK標識符:此部分是可選的,用於指定沒法訪問資源時的後備網頁。其中第一個 URI 表明資源,第二個表明後備網頁。兩個 URI 必須相關,而且必須與清單文件同源。可以使用通配符。

在聲明好描述文件的後,須要將描述文件與頁面關聯起來。在文檔的 html 標記中添加 manifest 屬性:

<html manifest='/offline.manifest'>
注1:描述文件擴展名之前推薦使用manifest,但如今推薦的是appcache。
注2:網站的應用緩存數據量不得超過5MB。
注3:系統會自動緩存引入描述清單的HTML文件,不過仍是建議將其寫入到描述清單中。

更新緩存

瀏覽器除了在第一次訪問 Web 應用時緩存資源外,只有在如下三種狀況纔會對緩存進行更新:

  1. 瀏覽器緩存被刪除
  2. manifest描述文件自己發生變化
  3. 應用緩存經過編程方式進行更新

而cache manifest中的資源文件發生變化並不會觸發更新,因此在對資源進行更改後,須要向描述文件中加入時間戳或版本號。

要以編程方式對緩存進行更新,須要用到緩存對象window.applicationCache。可使用它的屬性window.applicationCache來判斷緩存狀態,所有狀態以下:

 

  • 0:UNCACHED-沒有與頁面相關的應用緩存
  • 1:IDLE-應用緩存未更新
  • 2:CHECKING-正在檢查描述文件是否更新
  • 3:DOWNLOADING-下載中
  • 4:UPDATEREADY-更新完成
  • 5:OBSOLETE-描述文件不存在了,不能獲取應用緩存

比較經常使用的緩存狀態UPDATEREADY,當判斷緩存更新完成,就能夠對瀏覽器應用緩存,並進行刷新。與之相同的還有緩存事件:

  • checking:瀏覽器在爲應用緩存查找更新時觸發
  • error:查找錯誤時觸發
  • noupdate:檢查後發現描述文件無變化時觸發
  • downloading:開始下載應用緩存資源時觸發
  • progress:在下載應用緩存資源時不斷的觸發
  • updateready:應用緩存已經更新完畢,此時能夠手動觸發swapCache()應用更新的緩存
  • cached:在應用緩存完整可用時觸發

通常來說,這些事件會隨着頁面加載按上述順序依次觸發。不過,經過調用 update()方法也能夠手工干預,讓應用緩存爲檢查更新而觸發上述事件。在調用update()後,咱們一般使用updateready()和swapCache(),實現對瀏覽器緩存的更新,具體步驟以下:

window.applicationCache.update();        //手動檢測更新

window.applicationCache.addEventListener('updateready', function(){
  if(window.applicationCache.status == window.applicationCache.UPDATEREADY){ 
    window.applicationCache.swapCache();        //應用更新
    if(confirm('是否應用新的緩存?')){
      window.location.reload();                 //刷新頁面
    }
  }
  else{
    //沒有緩存更新
  }
})
注:You can programmatically test to see if an application has an updated cache manifest file, using JavaScript. Since a cache manifest file may have been updated before a script attaches event listeners to test for updates, scripts should always test .window.applicationCache.status

 

本地存儲

Cookie

Cookie是最基礎的存儲方式,主要用於服務器對用戶登錄的判斷。服務器會對每個HTTP請求發送Set-Cookie做爲HTTP頭的一部分,瀏覽器會保存該部份內容,並在以後的每一個請求頭中加入該Cookie,以便服務器識別請求的來源。

Cookie由名字,值,域,路徑,失效時間和安全標誌組成。其中域和路徑發送該Cookie的地址;失效時間是表示該Cookie什麼時候被刪除的時間戳(默認狀況下,瀏覽器會在回話關閉時刪除全部Cookie,不過咱們也能夠本身設置刪除時間);而指定安全標誌後,Cookie只有經過SSL鏈接才能傳輸。大致結構以下:

HTTP/1.1200 OK
Content-type: text/html
Set-Cookie: name=value; expires=Mon,22-Jan-0707:10:24 GMT; domain=.wrox.com; path=/; secure
Other-header: other-header-value

咱們可使用BOM提供的接口document.cookie來設置Cookie,上述參數中只有name/value是必選項,只要name沒有重複,爲cookie賦值是不會覆蓋已有信息的。不過這樣作有點蹩腳,就像下面的代碼同樣:

document.cookie = encodeURIComponent('name') + '=' + encodeURIComponent('pansy');

因此咱們一般爲Cookie封裝新的函數來進行操做,下面封裝實現了對Cookie值的增刪和查詢,能夠把這種經常使用操做加入到本身的庫裏:

var CookieUtil = {
    set: function(name, value, domain, path, expires, secure){  //前兩個是必填的
        var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
        if(domain){
            cookieText += '; domain=' + encodeURIComponent(domain);
        }
        if(path){
            cookieText += '; path=' + encodeURIComponent(path);
        }
        if(expires instanceof Date){
            cookieText += '; expires=' + expire.toGMTString;
        }
        if(secure){
            cookieText += '; secure';
        }
        document.cookie = cookieText;
    },
    get: function(name){
        cookieName = encodeURIComponent(name);     //必定不要忘記進行URL編碼
        cookieStart = document.cookie.indexOf(name);
        cookieValue = null;
        if(cookieStart != -1){
            cookieEnd = document.cookie.indexOf(';', cookieStart);
            if(cookieEnd == -1){
                cookieEnd = document.cookie.length;
            }
            cookieValue = document.cookie.slice(cookieStart, cookieEnd);   //或者使用string.prototype.substring
        }
        return cookieValue;
    },
    del: function(name){
        this.set(name,"",new Date(0))
    }    
}

因爲全部的 cookie 都會由瀏覽器做爲請求頭髮送,因此在 cookie 中存儲大量信息會影響到特定域的請求性能。 cookie 信息越大,完成對服務器請求的時間也就越長。儘管瀏覽器對 cookie 進行了大小限制,不過最好仍是儘量在 cookie 中少存儲信息,以免影響性能。
cookie 的性質和它的侷限使得其並不能做爲存儲大量信息的理想手段,因此又出現了其餘方法。

 

Storage

cookie提供的本地存儲空間十分有限(要否則怎麼叫小餅乾呢~),一般只有幾K,因此HTML5引用了Storage來進行本地存儲,Storage 類型提供最大的存儲空間來存儲名值對兒(key/value)。DOM Storage 分爲兩類:sessionStorage 和 localStorage。除了如下區別外,這兩類存儲對象的功能是徹底一致的(由於它們同屬一種Storage類型)。

  1. sessionStorage 用於存儲與當前瀏覽器窗口關聯的數據。窗口關閉後,sessionStorage 中存儲的數據將沒法使用。
  2. localStorage 用於長期存儲數據。窗口關閉後,localStorage 中的數據仍然能夠被訪問。全部瀏覽器窗口能夠共享 localStorage 的數據。

對Storage的操做能夠經過方法或者屬性來實現,下面以localStorage爲例,sessionStorage與之相同:

//設置、讀取、刪除變量
//使用方法
localStorage.setItem("name", "Pansy");
var name = localStorage.getItem("name")
localStorage.removeItem("name");

//使用屬性
localStorage.book ="Professional Javascript";
var book = localStorage.book;
remove localStorage.book;

 

備忘錄實例

 使用HTML5本地存儲作了一個備忘錄的實例,以下圖所示,進一步的代碼能夠在GitHub上獲取:

本地存儲demo -- webpansy

 

參考文章:
HTML5 localStorage本地存儲實際應用舉例 « 張鑫旭
相關文章
相關標籤/搜索