本篇文章會詳細介紹使用HTML5開發離線應用的步驟,以及本地存儲與cookie的一些異同,最後利用上面所學例子來實現一個購物車場景。css
使用HTML5離線存儲的基本過程以下:html
離線檢測:首先要對設備進行離線狀態檢測,根據設備在線或者離線判斷接下來的操做;html5
離線緩存:將須要被緩存的資源寫在一個描述文件(cache manifest)裏,當設備在線時進行緩存,以便用戶在離線時能夠正常使用;git
本地存儲:離線時,把必要的數據存儲到本地,當設備上線時將數據存儲到服務器上。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
描述文件的基本格式以下:安全
CACHE MANIFEST
後的文件)後顯式緩存這些文件;在聲明好描述文件的後,須要將描述文件與頁面關聯起來。在文檔的 html
標記中添加 manifest 屬性:
<html manifest='/offline.manifest'>
注1:描述文件擴展名之前推薦使用manifest,但如今推薦的是appcache。
注2:網站的應用緩存數據量不得超過5MB。
注3:系統會自動緩存引入描述清單的HTML文件,不過仍是建議將其寫入到描述清單中。
瀏覽器除了在第一次訪問 Web 應用時緩存資源外,只有在如下三種狀況纔會對緩存進行更新:
而cache manifest中的資源文件發生變化並不會觸發更新,因此在對資源進行更改後,須要向描述文件中加入時間戳或版本號。
要以編程方式對緩存進行更新,須要用到緩存對象window.applicationCache。可使用它的屬性window.applicationCache來判斷緩存狀態,所有狀態以下:
比較經常使用的緩存狀態UPDATEREADY,當判斷緩存更新完成,就能夠對瀏覽器應用緩存,並進行刷新。與之相同的還有緩存事件:
通常來說,這些事件會隨着頁面加載按上述順序依次觸發。不過,經過調用 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是最基礎的存儲方式,主要用於服務器對用戶登錄的判斷。服務器會對每個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 的性質和它的侷限使得其並不能做爲存儲大量信息的理想手段,因此又出現了其餘方法。
cookie提供的本地存儲空間十分有限(要否則怎麼叫小餅乾呢~),一般只有幾K,因此HTML5引用了Storage來進行本地存儲,Storage 類型提供最大的存儲空間來存儲名值對兒(key/value)。DOM Storage 分爲兩類:sessionStorage 和 localStorage。除了如下區別外,這兩類存儲對象的功能是徹底一致的(由於它們同屬一種Storage類型)。
對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上獲取:
參考文章:
HTML5 localStorage本地存儲實際應用舉例 « 張鑫旭