支持離線web應(yīng)用開(kāi)發(fā)是HTML5的另一個(gè)重點(diǎn)。所謂離線web應(yīng)用攻臀,就是在設(shè)備不能上網(wǎng)的情況下仍然可以運(yùn)行的應(yīng)用焕数。
23.1 離線檢測(cè)
if( navigator.onLine ){
//正常工作
} else {
//執(zhí)行離線狀態(tài)時(shí)的任務(wù)
}
為了更好的確定網(wǎng)絡(luò)是否可用,HTML5還定義了兩個(gè)事件:online和offline刨啸。當(dāng)網(wǎng)絡(luò)從離線變?yōu)樵诰€或者從在線變?yōu)殡x線時(shí)堡赔,分別觸發(fā)這兩個(gè)事件。這兩個(gè)事件在window對(duì)象上觸發(fā)设联。
$(window).on('online', function(){
alert('online')
})
$(window).on('offline', function(){
alert('offline')
})
23.2 應(yīng)用緩存
HTML5的應(yīng)用緩存善已,簡(jiǎn)稱(chēng) appcache 灼捂,是專(zhuān)門(mén)為開(kāi)發(fā)離線web應(yīng)用而設(shè)計(jì)的。Appcache 就是從瀏覽器的緩存中分出來(lái)的一塊緩存區(qū)雕拼。
雖然應(yīng)用緩存的意圖是確保離線時(shí)資源可用纵东,但也有相應(yīng)的JS API讓你知道它都在做什么。
這個(gè)API的核心是 applicationCache 對(duì)象啥寇,這個(gè)對(duì)象里有一個(gè) status 屬性偎球,表示應(yīng)用緩存的如下當(dāng)前狀態(tài):
23.3 數(shù)據(jù)存儲(chǔ)
隨著 Web 應(yīng)用程序的出現(xiàn),也產(chǎn)生了對(duì)于能夠直接在客戶(hù)端上存儲(chǔ)用戶(hù)信息能力的要求辑甜。
23.3.1 Cookie
HTTP Cookie衰絮,通常直接叫做cookie,最初是在客戶(hù)端用于存儲(chǔ)會(huì)話信息的磷醋。
限制
cookie有大小限制猫牡,超過(guò)限制,IE和Opera會(huì)刪除最近最少使用過(guò)的cookie邓线,騰出空間給新cookie淌友。Firefox會(huì)隨機(jī)刪除cookie,所以限制cookie非常重要骇陈,以免出現(xiàn)不可預(yù)期的后果震庭。cookie的構(gòu)成
(1) 名稱(chēng):一個(gè)唯一確定cookie的名稱(chēng),不區(qū)分大小寫(xiě)你雌,名稱(chēng)必須是經(jīng)過(guò)URL編碼的器联。
(2) 值:存儲(chǔ)在cookie中的字符串值,值必須被URL編碼
(3) 域:cookie對(duì)于哪個(gè)域是有效的婿崭。所有向該域發(fā)送的請(qǐng)求中都會(huì)包含這個(gè)cookie信息拨拓,默認(rèn)為設(shè)置cookie的那個(gè)域。
(4) 路徑:對(duì)于指定域中的那個(gè)路徑氓栈,應(yīng)該向服務(wù)器發(fā)送cookie
(5) 失效時(shí)間:表示 cookie 何時(shí)應(yīng)該被刪除的時(shí)間戳(也就是說(shuō)渣磷,何時(shí)應(yīng)該停止向服務(wù)器發(fā)送這個(gè)cookie)。默認(rèn)情況下颤绕,瀏覽器會(huì)話結(jié)束時(shí)即將所有 cookie 刪除幸海;
(6) 安全標(biāo)志:指定后, cookie只有在使用SSL連接的時(shí)候才發(fā)送到服務(wù)器。JavaScript 中的 cookie
document.cookie 返回當(dāng)前頁(yè)面可用的所有 cookie 的字符串奥务,一系列由分號(hào)隔開(kāi)的名值對(duì)兒。
所有名字和值都是經(jīng)過(guò) URL 編碼的袜硫,所以必須使用 decodeURIComponent() 來(lái)解碼
JS中基本的 cookie 操作有三種:讀取氯葬、寫(xiě)入和刪除,可以包裝成下面函數(shù):
var CookieUtil = {
get: function (name){
var cookieName = encodeURIComponent(name) + '=',
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if ( cookieStart > -1 ){
var cookieEnd = document.cookie.indexOf(';', cookieStart);
if( cookieEnd == -1 ){
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring( cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
},
set: function(name, value, expires, path, domain, secure){
var cookieText = encodeURIComponent(name) + '=' +
encodeURIComponent(value);
if( expires instanceof Date ){
cookieText += "; expires=" + expires.toGMTString();
}
if( path ){
cookieText += "; path=" + path;
}
if( domain ){
cookieText += "; domain=" + domain;
}
if( secure ){
cookieText += '; secure';
}
document.cookie = cookieText;
},
unset: function(name, path, domain, secure){
this.set(name, "", new Date(0), path, domain, secure);
}
}
子cookie
關(guān)于cookie的思考
cookie的性質(zhì)和它的局限性使得其并不能作為存儲(chǔ)大量信息的理想字段婉陷,所以又有其他方法帚称。
由于cookie的開(kāi)放訪問(wèn)性官研,所以不能在cookie中存儲(chǔ)重要和敏感的數(shù)據(jù)。
23.3.3 Web存儲(chǔ)機(jī)制
Web Storage的目的是克服由 cookie 帶來(lái)的一些限制闯睹,當(dāng)數(shù)據(jù)需要被嚴(yán)格控制在客戶(hù)端上時(shí)戏羽,無(wú)須持續(xù)地將數(shù)據(jù)發(fā)回服務(wù)器。Web Storage的兩個(gè)主要目標(biāo)是:
(1) 提供一種在 cookie 之外存儲(chǔ)會(huì)話數(shù)據(jù)的途徑楼吃;
(2) 提供一種存儲(chǔ)大量可以跨會(huì)話存在的數(shù)據(jù)的機(jī)制始花。
- Storage 類(lèi)型
有如下方法:
clear():刪除所有值。
getItem(name):根據(jù)指定的名字name獲取對(duì)應(yīng)的值孩锡。
key(index):獲得index位置處的值的名字酷宵。
removeItem(name):刪除由name指定的名值對(duì)兒。
setItem(name, value):為指定的name設(shè)置一個(gè)對(duì)應(yīng)的值躬窜。
- sessionStorage 對(duì)象
sessionStorage 對(duì)象存儲(chǔ)特定于某個(gè)會(huì)話的數(shù)據(jù)浇垦,也就是該數(shù)據(jù)只保持到瀏覽器關(guān)閉。這個(gè)對(duì)象就像會(huì)話 cookie荣挨,也會(huì)在瀏覽器關(guān)閉后消失男韧。存儲(chǔ)在 sessionStorage 中的數(shù)據(jù)可以跨越頁(yè)面刷新而存在。
sessionStorage對(duì)象是 Storage 的一個(gè)實(shí)例
存儲(chǔ)數(shù)據(jù):
//使用方法存儲(chǔ)數(shù)據(jù)
sessionStorage.setItem('name', 'Nick');
//使用屬性存儲(chǔ)數(shù)據(jù)
sessionStorage.book = 'JavaScript Book';
讀取數(shù)據(jù)
//使用方法讀取數(shù)據(jù)
var name = sessionStorage.getItem('name');
//使用屬性讀取數(shù)據(jù)
var book = sessionStorage.book;
刪除數(shù)據(jù)
//使用 delete 刪除一個(gè)值-在webkit中無(wú)效
delete sessionStorage.name;
//使用方法刪除一個(gè)值
sessionStorage.removeItem('book');
使用循環(huán)迭代出sessionStorage中數(shù)據(jù):
for (var i = 0, len = sessionStorage.length; i < len; i++){
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key);
console.log(key + '=' + value);
}
sessionStorage對(duì)象主要用于僅針對(duì)會(huì)話的小段數(shù)據(jù)的存儲(chǔ)默垄。如果需要跨越會(huì)話存儲(chǔ)數(shù)據(jù)此虑,那么 globalStorage 或者 localStorage 更為合適。
- localStorage 對(duì)象
localStorage 對(duì)象在修訂過(guò)的 HTML5 規(guī)范中做為持久保存客戶(hù)端數(shù)據(jù)的方案取代了 globalStorage厕倍。
由于 localStorage 是 Storage 的實(shí)例寡壮,所以可以有以下方法:
//使用方法存儲(chǔ)數(shù)據(jù)
localStorage.setItem('name', 'Nick');
//使用屬性存儲(chǔ)數(shù)據(jù)
localStorage.book = 'JavaScript book';
//使用方法讀取數(shù)據(jù)
var name = localStorage.getItem('name');
//使用屬性讀取數(shù)據(jù)
var book = localStorage.book;
存儲(chǔ)在 localStorage 中的數(shù)據(jù)會(huì)保留到通過(guò) JavaScript 刪除或者是用戶(hù)清除瀏覽器緩存。
由于有的瀏覽器只兼容 globalStorage讹弯,所以可以有以下兼容方案:
function getLocalStorage(){
if ( typeof localStorage == "object" ){
return localStorage;
} else if( typeof globalStorage == "object" ){
return globalStorage[location.host];
} else {
throw new Error('Local storage not available');
}
}
var storage = getLocalStorage();
- storage 事件
對(duì) Storage 對(duì)象進(jìn)行任何修改况既,都會(huì)在文檔上觸發(fā) storage 事件
$(document).on('storage', function(event ){
})
無(wú)論是對(duì) sessionStorage、globalStorage還是localStorage進(jìn)行操作组民,都會(huì)觸發(fā) storage 事件棒仍,但不區(qū)分。
23.3.4 IndexedDB
是在瀏覽器中保存結(jié)構(gòu)化數(shù)據(jù)的一種數(shù)據(jù)庫(kù)臭胜,IndexedDB的思想是創(chuàng)建一套 API莫其,方便保存和讀取 JS對(duì)象,同時(shí)還支持查詢(xún)及搜索耸三。