本文是關(guān)于客戶端存儲(chǔ)(client-side storage)的。這是一個(gè)通用術(shù)語(yǔ),包含幾個(gè)獨(dú)立但相關(guān)的 API: Web Storage、Web SQL Database、Indexed Database 和 File Access。每種技術(shù)都提供了在用戶硬盤上 —— 而非通常存儲(chǔ)數(shù)據(jù)的服務(wù)器 —— 存儲(chǔ)數(shù)據(jù)的獨(dú)特方式。這么做主要基于以下兩點(diǎn)理由:(a)使 web app 離線可用; (b)改善性能。
這些 API 有著類似的作用范圍和規(guī)則。我們先了解他們的共同之處吧。
共同特點(diǎn)基于客戶端的存儲(chǔ)
實(shí)際上,“客戶端時(shí)間存儲(chǔ)”的意思是,數(shù)據(jù)傳給了瀏覽器的存儲(chǔ) API,它將數(shù)據(jù)存在本地設(shè)備中的一塊區(qū)域,該區(qū)域同樣也是它存儲(chǔ)其他用戶特定信息如個(gè)人偏好、緩存的地方。除了存儲(chǔ)數(shù)據(jù),這些 API 可以用來(lái)檢索數(shù)據(jù),且在某些情況下還能執(zhí)行搜索和批處理操作。
置于沙盒中的
所有這四個(gè)存儲(chǔ) API 都將數(shù)據(jù)綁到一個(gè)單獨(dú)的“源”(origin)上。例如,若 http://abc.example.com保存了一些數(shù)據(jù),那以后瀏覽器就只會(huì)允許 http://abc.example.com獲取這些數(shù)據(jù)。當(dāng)我們談?wù)?ldquo;源”(origin)的時(shí)候,這意味著域(domain)必須完全相同,所以 http://example.com和 http://def.example.com都不行。端口(port)也必須匹配,因此 http://abc.example.com:123也是不能訪問(wèn)到 http://abc.example.com(端口默認(rèn)為80)存儲(chǔ)的數(shù)據(jù)。同樣,協(xié)議也必須一樣(像http vs https 等等)。
空間限制(Quotas)
你能想象,如果任何網(wǎng)站都被允許往毫不知情的硬盤里填充以千兆字節(jié)計(jì)的數(shù)據(jù),該有多混亂。因此,瀏覽器對(duì)存儲(chǔ)容量施加了限制。若你的應(yīng)用試圖超出限制,瀏覽器通常會(huì)顯示一個(gè)對(duì)話框,讓用戶確認(rèn)增加。您可能以為瀏覽器對(duì)單個(gè)源(origin)可使用的所有存儲(chǔ)都加以同一單獨(dú)的限制,但多數(shù)存儲(chǔ)機(jī)制都是單獨(dú)加以限制的。若 Quota API被采納,這種情況可能會(huì)改變。但就現(xiàn)在來(lái)說(shuō),把瀏覽器當(dāng)作一個(gè)二維矩陣,其維度分別是“源”(origin)和“存儲(chǔ)”(storage)。例如, “http://abc.example.com” 可能會(huì)允許最多存 5MB 的 Web Storage, 25MB 的 Web SQL 數(shù)據(jù)庫(kù),但因用戶拒絕訪問(wèn)被禁止使用 Indexed DataBase。 Quota API 將問(wèn)題放到一起來(lái)看,讓您查詢還有多少可用空間,有多少空間正在使用。
有些情況下,用戶也能先看到有多少存儲(chǔ)將被使用,例如,當(dāng)用戶在 Chrome 應(yīng)用商店中安裝一個(gè)應(yīng)用時(shí),他們將被提示預(yù)先接受其權(quán)限,其中包括存儲(chǔ)限制。(而該應(yīng)用的)manifest 中的可能有個(gè)值是 “unlimited_storage” (無(wú)限制存儲(chǔ))。
數(shù)據(jù)庫(kù)處理(Transactions)
兩個(gè) “數(shù)據(jù)庫(kù)” 的存儲(chǔ)格式支持?jǐn)?shù)據(jù)處理。目的和通常的關(guān)系型數(shù)據(jù)庫(kù)使用數(shù)據(jù)處理是一樣的:保證數(shù)據(jù)庫(kù)完整。數(shù)據(jù)庫(kù)處理(Transactions)防止 “競(jìng)爭(zhēng)條件”(race conditions) —— 這種情況是:當(dāng)兩個(gè)操作序列在同一時(shí)間被應(yīng)用到數(shù)據(jù)庫(kù)中, 導(dǎo)致操作結(jié)果都無(wú)法被預(yù)測(cè),而數(shù)據(jù)庫(kù)也處于可疑的準(zhǔn)確性(dubious accuracy)狀態(tài)。
同步和異步模式(Synchronous and Asynchronous Modes)
多數(shù)存儲(chǔ)格式都支持同步和異步模式。同步模式是阻塞的,意味著下一行 js 代碼執(zhí)行之前,存儲(chǔ)操作會(huì)被完整執(zhí)行。異步模式會(huì)使得后面的 js 代碼在數(shù)據(jù)庫(kù)操作完成之前執(zhí)行。存儲(chǔ)操作會(huì)背景環(huán)境中執(zhí)行,當(dāng)操作完成的時(shí)候,應(yīng)用會(huì)以回調(diào)函數(shù)被調(diào)用這種形式接收通知,這個(gè)函數(shù)須在調(diào)用的時(shí)候被指定。
應(yīng)當(dāng)盡量避免使用同步模式,它雖然看起來(lái)比較簡(jiǎn)單,但操作完成時(shí)它會(huì)阻塞頁(yè)面渲染,在某些情況下甚至?xí)鼋Y(jié)整個(gè)瀏覽器。你可能注意到網(wǎng)站乃至是應(yīng)用出現(xiàn)這種情況,點(diǎn)擊一個(gè)按鈕,結(jié)果所有東西都用不了,當(dāng)你還在想是不是崩潰了?結(jié)果一切又突然恢復(fù)正常了。
某些 API 沒(méi)有異步模式,如“localStorage”, 使用這些API時(shí),應(yīng)當(dāng)仔細(xì)做好性能監(jiān)測(cè),并隨時(shí)準(zhǔn)備切換到一個(gè)異步API,如果它造成了問(wèn)題。
API
Web Storage是一個(gè)叫做 localStorage 的持久對(duì)象??梢允褂?localStorage.foo = "bar" 保存值,之后可以使用 localStorage.foo 獲取到 —— 甚至是瀏覽器關(guān)閉之后重新打開。還可以使用一個(gè)叫做 sessionStorage 的對(duì)象,工作方式一樣,只是當(dāng)窗口關(guān)閉之后會(huì)被清除掉。
Web Storage 是 NoSQL 鍵值對(duì)儲(chǔ)存(NoSQL key-value store)的一種.
Web Storage
數(shù)年以來(lái),被所有現(xiàn)代瀏覽器支持, iOS 和 Android 系統(tǒng)下也支持(IE 從 IE8 開始支持 )。
簡(jiǎn)單的API簽名。
同步 API,調(diào)用簡(jiǎn)單。
語(yǔ)義事件可保持其他標(biāo)簽和窗口同步。
Web Storage
使用同步 API(這是得到最廣泛支持的模式)存儲(chǔ)大量的或者復(fù)雜的數(shù)據(jù)時(shí)性能差。
缺少索引導(dǎo)致檢索大量的或復(fù)雜的數(shù)據(jù)時(shí)性能差。(搜索操作需要手動(dòng)遍歷所有項(xiàng)。)
存儲(chǔ)或讀取大量的或復(fù)雜的數(shù)據(jù)結(jié)構(gòu)時(shí)性能差,因?yàn)樾枰謩?dòng)序序列化成字符串或?qū)⒆址葱蛄谢?。主要的瀏覽器實(shí)現(xiàn)只支持字符串(盡管規(guī)范沒(méi)這么說(shuō)的)。
需要保證數(shù)據(jù)的持續(xù)性和完整性,因?yàn)閿?shù)據(jù)是有效非結(jié)構(gòu)化(effectively unstructured)的。
Web SQL Database
Web SQL Database是一個(gè)結(jié)構(gòu)化的數(shù)據(jù)庫(kù),具備典型 SQL驅(qū)動(dòng)的關(guān)系數(shù)據(jù)庫(kù)(SQL-powered relational database)的所有功能和復(fù)雜度。Indexed Database 在兩者之間。Web SQL Database有自由形式的密鑰值對(duì),有點(diǎn)像 Web Storage,但也有能力從這些值來(lái)索引字段,所以搜索速度要快得多。
Web SQL Database
被主要的移動(dòng)瀏覽器(Android Browser, Mobile Safari, Opera Mobile)以及一些 PC 瀏覽器(Chrome, Safari, Opera) 支持。
作為異步 API, 總體而言性能很好。數(shù)據(jù)庫(kù)交互不會(huì)鎖定用戶界面。(同步API也可用于 WebWorkers。)
良好的搜索性能,因?yàn)閿?shù)據(jù)可以根據(jù)搜索鍵進(jìn)行索引。
強(qiáng)大,因?yàn)樗С质聞?wù)性數(shù)據(jù)庫(kù)模型(transactional database model)。
剛性的數(shù)據(jù)結(jié)構(gòu)更容易保持?jǐn)?shù)據(jù)的完整性。
Web SQL Database
過(guò)時(shí),不會(huì)被 IE 或 Firefox 支持,在某些階段可能會(huì)被從其他瀏覽器淘汰。
學(xué)習(xí)曲線陡峭,要求掌握關(guān)系數(shù)據(jù)庫(kù)和SQL的知識(shí)。
對(duì)象-關(guān)系阻抗失配(object-relational impedance mismatch).
降低敏捷性,因?yàn)閿?shù)據(jù)庫(kù)模式必須預(yù)先定義,與表中的所有記錄必須匹配相同的結(jié)構(gòu)。
Indexed Database (IndexedDB)
到目前為止,我們已經(jīng)看到,Web Storage 和 Web SQL Database 都有各種的優(yōu)勢(shì)和弱點(diǎn)。 Indexed Database產(chǎn)生于這兩個(gè)早期 API 的經(jīng)驗(yàn),可以看作是一種結(jié)合兩者優(yōu)點(diǎn)而不招致其劣勢(shì)得到嘗試。
Indexed Database 是一個(gè) “對(duì)象存儲(chǔ)” (object stores) 的集合,可以直接把對(duì)象放進(jìn)去。這個(gè)存儲(chǔ)有點(diǎn)像 SQL 表,但在這種情況下,對(duì)象的結(jié)構(gòu)沒(méi)有約束,所以不需要預(yù)先定義什么。所以這和 Web Storage 有點(diǎn)像,擁有多個(gè)數(shù)據(jù)庫(kù)、每個(gè)數(shù)據(jù)庫(kù)又有多個(gè)存儲(chǔ)(store)的特點(diǎn)。但不像 Web Storage那樣, 還擁有重要的性能優(yōu)勢(shì): 異步接口,可以在存儲(chǔ)上創(chuàng)建索引,以提高搜索速度。
IndexedDB
作為異步API總體表現(xiàn)良好。數(shù)據(jù)庫(kù)交互不會(huì)鎖定用戶界面。(同步 API 也可用于 WebWorkers。)
良好的搜索性能,因?yàn)閿?shù)據(jù)可以根據(jù)搜索鍵進(jìn)行索引。
支持版本控制。
強(qiáng)大,因?yàn)樗С质聞?wù)性數(shù)據(jù)庫(kù)模型(transactional database model)。
因?yàn)閿?shù)據(jù)模型簡(jiǎn)單,學(xué)習(xí)曲線也相當(dāng)簡(jiǎn)單。
良好的瀏覽器支持: Chrome, Firefox, mobile FF, IE10.
IndexedDB
非常復(fù)雜的API,導(dǎo)致大量的嵌套回調(diào)。
FileSystem
上面的 API 都是適用于文本和結(jié)構(gòu)化數(shù)據(jù),但涉及到大文件和二進(jìn)制內(nèi)容時(shí),我們需要一些其他的東西。幸運(yùn)的是,我們現(xiàn)在有了文件系統(tǒng) API 標(biāo)準(zhǔn)(FileSystem API standard)。它給每個(gè)域一個(gè)完整的層次化的文件系統(tǒng),至少在 Chrome 下面,這些都是用戶的硬盤上的真正的文件。就單個(gè)文件的讀寫而言, API 建立在現(xiàn)有的 File API之上。
FileSystem
可以存儲(chǔ)大量的內(nèi)容和二進(jìn)制文件,很適合圖像,音頻,視頻,PDF,等。
作為異步 API, 性能良好。
FileSystem API
很早的標(biāo)準(zhǔn),只有 Chrome 和 Opera 支持。
沒(méi)有事務(wù)(transaction)支持。
沒(méi)有內(nèi)建的搜索/索引支持。
以上便是這些API的共同之處。
分享到微信 ×
打開微信,點(diǎn)擊底部的“發(fā)現(xiàn)”,
使用“掃一掃”即可將網(wǎng)頁(yè)分享至朋友圈。