JavaScript 高級程序設(shè)計(jì)(第23 離線應(yīng)用與客戶端存儲(chǔ))

第23 離線應(yīng)用與客戶端存儲(chǔ)

1. 離線檢測

(1)navigator.onLine 屬性,這個(gè)屬性值為true表示設(shè)備能上網(wǎng),值為false表示設(shè)備離線。
(2)兩個(gè)事件: online 和 offline。當(dāng)網(wǎng)絡(luò)從離線變?yōu)樵诰€或者從在線變?yōu)殡x線時(shí),分別觸發(fā)這兩個(gè)事件。這兩個(gè)事 件在 window 對象上觸發(fā)映之。

2. 應(yīng)用緩存

(1) HTML5 的應(yīng)用緩存(application cache),或者簡稱為 appcache,是專門為開發(fā)離線 Web 應(yīng)用而設(shè)計(jì) 的穴豫。Appcache 就是從瀏覽器的緩存中分出來的一塊緩存區(qū)皮钠。要想在這個(gè)緩存中保存數(shù)據(jù),可以使用一個(gè)描述文件(manifest file),列出要下載和緩存的資源晚岭。
(2) 要將描述文件與頁面關(guān)聯(lián)起來,可以在<html>中的 manifest 屬性中指定這個(gè)文件的路徑<htmlmanifest="/offline.manifest">
這個(gè)文件的 MIME 類型必須是 text/cache-manifest1迂烁。
(3) applicationCache 對象,這個(gè)對象有一個(gè) status 屬性,屬性的值是常量,表示應(yīng)用緩存的如下當(dāng)前狀態(tài)州袒。

  • 0:無緩存,即沒有與頁面相關(guān)的應(yīng)用緩存揭绑。
  • 1:閑置,即應(yīng)用緩存未得到更新。
  • 2:檢查中,即正在下載描述文件并檢查更新稳析。
  • 3:下載中,即應(yīng)用緩存正在下載描述文件中指定的資源洗做。
  • 4:更新完成,即應(yīng)用緩存已經(jīng)更新了資源,而且所有資源都已下載完畢,可以通過 swapCache()來使用了。
  • 5:廢棄,即應(yīng)用緩存的描述文件已經(jīng)不存在了,因此頁面無法再訪問應(yīng)用緩存彰居。

(4) 應(yīng)用緩存還有很多相關(guān)的事件,表示其狀態(tài)的改變诚纸。以下是這些事件。

  • checking:在瀏覽器為應(yīng)用緩存查找更新時(shí)觸發(fā)陈惰。
  • error:在檢查更新或下載資源期間發(fā)生錯(cuò)誤時(shí)觸發(fā)畦徘。
  • noupdate:在檢查描述文件發(fā)現(xiàn)文件無變化時(shí)觸發(fā)。
  • downloading:在開始下載應(yīng)用緩存資源時(shí)觸發(fā)抬闯。
  • progress:在文件下載應(yīng)用緩存的過程中持續(xù)不斷地觸發(fā)井辆。
  • updateready:在頁面新的應(yīng)用緩存下載完畢且可以通過 swapCache()使用時(shí)觸發(fā)。
  • cached:在應(yīng)用緩存完整可用時(shí)觸發(fā)

(5) update()方法也可以 手工干預(yù),讓應(yīng)用緩存為檢查更新而觸發(fā)上述事件溶握。applicationCache.update();
(6) 如果觸發(fā)了 updateready 事件,則說明新版本的應(yīng)用緩存已經(jīng)可用,而此時(shí)你需 要調(diào)用swapCache()來啟用新應(yīng)用緩存杯缺。

EventUtil.addHandler(applicationCache, "updateready", function(){ 
applicationCache.swapCache();
});

3. 數(shù)據(jù)存儲(chǔ)

(1) Cookie

  1. HTTP Cookie,通常直接叫做 cookie,最初是在客戶端用于存儲(chǔ)會(huì)話信息的。該標(biāo)準(zhǔn)要求服務(wù)器對任意 HTTP 請求發(fā)送 Set-Cookie HTTP 頭作為響應(yīng)的一部分,其中包含會(huì)話信息睡榆。
  2. 瀏覽器會(huì)存儲(chǔ)這樣的會(huì)話信息,并在這之后,通過為每個(gè)請求添加Cookie HTTP 頭將信 息發(fā)送回服務(wù)器萍肆。
* 限制

cookie 在性質(zhì)上是綁定在特定的域名下的袍榆。當(dāng)設(shè)定了一個(gè) cookie 后,再給創(chuàng)建它的域名發(fā)送請求時(shí), 都會(huì)包含這個(gè) cookie。這個(gè)限制確保了儲(chǔ)存在 cookie 中的信息只能讓批準(zhǔn)的接受者訪問,而無法被其他 域訪問塘揣。

  1. 每個(gè)域的 cookie 總數(shù)是有限的,不過瀏覽器之間各有不同包雀。
  2. 瀏覽器中對于 cookie 的尺寸也有限制。大多數(shù)瀏覽器都有大約 4096B(加減 1)的長度限制亲铡。
*cookie 的構(gòu)成

cookie 由瀏覽器保存的以下幾塊信息構(gòu)成:

  1. 名稱(name):一個(gè)唯一確定 cookie 的名稱才写。cookie 名稱是不區(qū)分大小寫的,所以 myCookie 和 MyCookie 被認(rèn)為是同一個(gè) cookie。然而,實(shí)踐中最好將 cookie 名稱看作是區(qū)分大小寫的,因?yàn)槟承┓?wù)器會(huì)這樣處理 cookie奖蔓。cookie 的名稱必須是經(jīng)過 URL 編碼的赞草。
  2. 值:儲(chǔ)存在 cookie 中的字符串值。值必須被 URL 編碼锭硼。
  3. 域(domain):cookie 對于哪個(gè)域是有效的房资。所有向該域發(fā)送的請求中都會(huì)包含這個(gè) cookie 信息蜕劝。這個(gè)值
    可以包含子域(subdomain,如 www.wrox.com),也可以不包含它(如.wrox.com,則對于 wrox.com的所有子域都有效)檀头。如果沒有明確設(shè)定,那么這個(gè)域會(huì)被認(rèn)作來自設(shè)置 cookie 的那個(gè)域。
  4. 路徑(path):對于指定域中的那個(gè)路徑,應(yīng)該向服務(wù)器發(fā)送 cookie岖沛。例如,你可以指定 cookie 只有從 http://www.wrox.com/books/ 中才能訪問,那么 http://www.wrox.com 的頁面就不會(huì)發(fā)送 cookie 信息,即使請求都是來自同一個(gè)域的暑始。
  5. 失效時(shí)間(expires):表示 cookie 何時(shí)應(yīng)該被刪除的時(shí)間戳(也就是,何時(shí)應(yīng)該停止向服務(wù)器發(fā)送這個(gè)
    cookie)。默認(rèn)情況下,瀏覽器會(huì)話結(jié)束時(shí)即將所有 cookie 刪除;不過也可以自己設(shè)置刪除時(shí)間婴削。 這個(gè)值是個(gè) GMT 格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT),用于指定應(yīng)該刪除 cookie 的準(zhǔn)確時(shí)間廊镜。因此,cookie 可在瀏覽器關(guān)閉后依然保存在用戶的機(jī)器上。如果你設(shè)置的失 效日期是個(gè)以前的時(shí)間,則 cookie 會(huì)被立刻刪除唉俗。
  6. 安全標(biāo)志(secure):指定后,cookie 只有在使用 SSL 連接的時(shí)候才發(fā)送到服務(wù)器嗤朴。例如,cookie 信息只 能發(fā)送給 https://www.wrox.com,而 http://www.wrox.com 的請求則不能發(fā)送 cookie
每一段信息都作為 Set-Cookie 頭的一部分,使用分號加空格分隔每一段

Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com

*JavaScript 中的 cookie
document. cookie 屬性。
  1. 當(dāng)用來獲取屬性值時(shí), document.cookie 返回當(dāng)前頁面可用的(根據(jù) cookie 的域虫溜、路徑雹姊、失效時(shí)間和安全設(shè)置)所有 cookie 的字符串,一系列由分號隔開的名值對兒.
  2. 當(dāng)用于設(shè)置值的時(shí)候,document.cookie 屬性可以設(shè)置為一個(gè)新的 cookie 字符串。這個(gè) cookie 字
    符串會(huì)被解釋并添加到現(xiàn)有的 cookie 集合中衡楞。設(shè)置 document.cookie 并不會(huì)覆蓋 cookie,除非設(shè)置的cookie 的名稱已經(jīng)存在吱雏。
*子 cookie

子 cookie 是存放在單個(gè) cookie 中的更小段的數(shù)據(jù)。也就是使用 cookie 值來存儲(chǔ)多個(gè)名稱值對 兒瘾境。子 cookie 最常見的的格式如下所示歧杏。
name=name1=value1&name2=value2&name3=value3&name4=value4

(2) IE用戶數(shù)據(jù)

在 IE5.0 中,微軟通過一個(gè)自定義行為引入了持久化用戶數(shù)據(jù)的概念。用戶數(shù)據(jù)允許每個(gè)文檔最多 128KB 數(shù)據(jù),每個(gè)域名最多 1MB 數(shù)據(jù)迷守。要使用持久化用戶數(shù)據(jù),首先必須如下所示,使用 CSS 在某個(gè) 元素上指定 userData 行為:
<div style="behavior:url(#default#userData)" id="dataStore"></div>

  1. 使用 setAttribute()方法保存數(shù)據(jù)犬绒。
  2. 為了將數(shù)據(jù)提交到瀏覽器緩存中,還必須調(diào)用save()方法并告訴它要保存到的數(shù)據(jù)空間的名字。數(shù)據(jù)空間名字可以完全任意,僅用于區(qū)分不同的數(shù)據(jù)集兑凿。
var dataStore = document.getElementById("dataStore");
dataStore.setAttribute("name", "Nicholas");
dataStore.setAttribute("book", "Professional JavaScript");
dataStore.save("BookInfo");
  1. 下一次頁面載入之后,可以使用 load()方法指定 同樣的數(shù)據(jù)空間名稱來獲取數(shù)據(jù)凯力。
  2. getAttribute()調(diào)用了不存在的名稱或者是尚未載入的名 稱,則返回 null眨业。
dataStore.load("BookInfo");
alert(dataStore.getAttribute("name")); //"Nicholas"
alert(dataStore.getAttribute("book")); //"Professional JavaScript"
  1. 通過removeAttribute()方法明確指定要?jiǎng)h除某元素?cái)?shù)據(jù),只要指定屬性名稱。刪除之后, 必須像下面這樣再次調(diào)用 save()來提交更改沮协。
 dataStore.removeAttribute("name");
dataStore.removeAttribute("book");
dataStore.save("BookInfo");

(3) Web存儲(chǔ)機(jī)制

*Storage 類型
  1. clear(): 刪除所有值;Firefox 中沒有實(shí)現(xiàn) 龄捡。
  2. getItem(name):根據(jù)指定的名字 name 獲取對應(yīng)的值。
  3. key(index):獲得 index 位置處的值的名字慷暂。
  4. removeItem(name):刪除由 name 指定的名值對兒聘殖。
  5. setItem(name, value):為指定的 name 設(shè)置一個(gè)對應(yīng)的值。
*sessionStorage 對象

sessionStorage對象存儲(chǔ)特定于某個(gè)會(huì)話的數(shù)據(jù),也就是該數(shù)據(jù)只保持到瀏覽器關(guān)閉行瑞。

  1. sessionStorage 對象其實(shí)是 Storage 的一個(gè)實(shí)例,所以可以使用 setItem()或者直接設(shè)奸腺。
  2. sessionStorage 中有數(shù)據(jù)時(shí),可以使用 getItem()或者通過直接訪問屬性名來獲取數(shù)據(jù)。
  3. 可以通過結(jié)合 length 屬性和 key()方法來迭代 sessionStorage 中的值血久。
  4. 可以使用 for-in 循環(huán)來迭代 sessionStorage 中的值突照。
  5. 可以使用 delete 操作符刪除對象屬性,也可調(diào)用 removeItem()方法。
*globalStorage 對象

globalStorage這個(gè)對象的目的是跨越會(huì)話存儲(chǔ)數(shù)據(jù),但有特定的訪問限制氧吐。要使用 globalStorage,首先要指定哪些域可以訪問該數(shù)據(jù)讹蘑。可以通過方括號標(biāo)記使用屬性來實(shí)現(xiàn)筑舅。

  1. 對 globalStorage 空間的訪問,是依據(jù)發(fā)起請求的頁面的域名座慰、協(xié)議和端口來限制的。
  2. 如果你事先不能確定域名,那么使用 location.host作為屬性名比較安全翠拣。
  3. 如果不使用 removeItem()或者 delete 刪除,或者用戶未清除瀏覽器緩存,存儲(chǔ)在 globalStorage 屬性中的數(shù)據(jù)會(huì)一直保留在磁盤上版仔。
*localStorage 對象

不能給localStorage指定任何訪問規(guī)則;規(guī)則事先就設(shè)定好了。要訪問同一個(gè) localStorage 對象,頁面必須來自同一個(gè)域名(子域名無效),使用同一種 協(xié)議,在同一個(gè)端口上误墓。這相當(dāng)于 globalStorage[location.host]蛮粮。

*storage 事件

這個(gè)事件的 event 對象有以下屬性。
(1) domain:發(fā)生變化的存儲(chǔ)空間的域名谜慌。
(2) key:設(shè)置或者刪除的鍵名然想。
(3) newValue:如果是設(shè)置值,則是新值;如果是刪除鍵,則是 null。
(4) oldValue:鍵被更改之前的值畦娄。

(4) IndexedDB

*數(shù)據(jù)庫

IndexedDB 最大的特色是使用對象保存數(shù)據(jù),而不是使用表來保存數(shù)據(jù)又沾。一個(gè) IndexedDB 數(shù)據(jù)庫,就是 一組位于相同命名空間下的對象的集合。

var indexedDB = window.indexedDB || window.msIndexedDB || window.mozIndexedDB || window.webkitIndexedDB;
  1. 把要打開的數(shù)據(jù)庫名傳給indexDB.open()熙卡。如果傳入的 數(shù)據(jù)庫已經(jīng)存在,就會(huì)發(fā)送一個(gè)打開它的請求;如果傳入的數(shù)據(jù)庫還不存在,就會(huì)發(fā)送一個(gè)創(chuàng)建并打開 它的請求杖刷。總之,調(diào)用 indexDB.open()會(huì)返回一個(gè) IDBRequest 對象,在這個(gè)對象上可以添加 onerror 和 onsuccess 事件處理程序驳癌。
var request, database;
request = indexedDB.open("admin");
request.onerror = function(event){
    alert("Something bad happened while trying to open: " +
           event.target.errorCode);
};
request.onsuccess = function(event){
    database = event.target.result;
};

(1) event.target.result中將有一個(gè)數(shù)據(jù)庫實(shí)例對象(IDBData- base),這個(gè)對象會(huì)保存在 database 變量中滑燃。
(2) 如果發(fā)生了錯(cuò)誤,那 event.target.errorCode中將 保存一個(gè)錯(cuò)誤碼,表示問題的性質(zhì)。

  1. 默認(rèn)情況下,IndexedDB 數(shù)據(jù)庫是沒有版本號的,最好一開始就為數(shù)據(jù)庫指定一個(gè)版本號颓鲜。為此, 可以調(diào)用setVersion()方法,傳入以字符串形式表示的版本號表窘。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末典予,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乐严,更是在濱河造成了極大的恐慌瘤袖,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件昂验,死亡現(xiàn)場離奇詭異捂敌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)既琴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門占婉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甫恩,你說我怎么就攤上這事逆济。” “怎么了磺箕?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵奖慌,是天一觀的道長。 經(jīng)常有香客問我滞磺,道長升薯,這世上最難降的妖魔是什么莱褒? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任击困,我火速辦了婚禮,結(jié)果婚禮上广凸,老公的妹妹穿的比我還像新娘阅茶。我一直安慰自己,他們只是感情好谅海,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布脸哀。 她就那樣靜靜地躺著,像睡著了一般扭吁。 火紅的嫁衣襯著肌膚如雪撞蜂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天侥袜,我揣著相機(jī)與錄音蝌诡,去河邊找鬼。 笑死枫吧,一個(gè)胖子當(dāng)著我的面吹牛浦旱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播九杂,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼颁湖,長吁一口氣:“原來是場噩夢啊……” “哼宣蠕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起甥捺,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤抢蚀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后镰禾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體思币,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年羡微,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谷饿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡妈倔,死狀恐怖博投,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盯蝴,我是刑警寧澤毅哗,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站捧挺,受9級特大地震影響虑绵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜闽烙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一翅睛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧黑竞,春花似錦捕发、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至遏匆,卻和暖如春法挨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背幅聘。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工凡纳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人喊暖。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓惫企,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子狞尔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • ??支持離線 Web 應(yīng)用開發(fā)是 HTML5 的另一個(gè)重點(diǎn)偏序。 ??所謂離線 Web 應(yīng)用页畦,就是在設(shè)備不能上網(wǎng)的情況...
    霜天曉閱讀 1,033評論 0 2
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)研儒,斷路器豫缨,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 支持離線web應(yīng)用開發(fā)是HTML5的另一個(gè)重點(diǎn)。所謂離線web應(yīng)用端朵,就是在設(shè)備不能上網(wǎng)的情況下仍然可以運(yùn)行的應(yīng)用好芭。...
    __越過山丘__閱讀 173評論 0 1
  • 開發(fā)離線Web應(yīng)用的步驟:1.檢測設(shè)備是否可以上網(wǎng);2.能訪問一定的資源冲呢;3.有一塊本地空間保存數(shù)據(jù)舍败。 1. 離線...
    xiaoguo16閱讀 336評論 2 3
  • 在寫這篇文章之前,我重新翻閱了自己的日記敬拓。從學(xué)習(xí)累積法開始到現(xiàn)在邻薯,我發(fā)現(xiàn)自己在不斷地調(diào)整,從前認(rèn)為重要的事情乘凸,到現(xiàn)...
    爬行中的小蝸牛閱讀 597評論 2 3