這是專門探索 JavaScript 及其所構建的組件的系列文章的第 16 篇。javascript
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等着你!前端
若是你錯過了前面的章節,能夠在這裏找到它們:java
在設計 Web 應用程序時,爲本地瀏覽器選擇合適的存儲機制相當重要, 一個好的存儲引擎能夠確保可靠地保存信息,減小帶寬,提升響應能力。正確的存儲緩存策略是實現離線移動 Web 體驗的核心構建塊,同時也大大的提升了用戶體驗。git
在本章中,討論可選擇的存儲 Api 和服務,並提供一些在構建 Web應用程序,該使用哪一種存儲引擎。github
數據存儲模型肯定數據在內部的組織方式,這會影響 Web 應用程序的整個設計,合理的數據模式會讓 Web 應用程序在完成它應有的任務下還能讓運行速度更加高效。對於全部與工程相關的問題,沒有存在最好的解決方法,也沒有適用於全部問題的解決方案,不一樣場景下有不一樣的選擇。因此,來看看可選擇的數據模型:web
Apache Cassandra 是一套開源分佈式數據庫管理系統,由Facebook開發,用於儲存特別大的數據。
web 應用程序的存儲方法能夠根據數據持久化的時間段進行劃分:數據庫
如今,有至關多的瀏覽器 Api 用來存儲數據。這裏將逐一介紹其中的一些及它們的區別,以便後續咱們可以容合理的選擇使用。編程
然而,在選擇如何持久化數據以前,有幾件事須要考慮。固然,有必要知道的的第一件事是你的 Web 應用程序應用場景是什麼,以及之後如何迭代和豐富。即便你知道了這些,最終也會有幾個選擇。因此,如下是須要了解的:segmentfault
在本節中,瞭解決 Web 開發人員的當前可用存儲 Api,並從各個維度上進行比較。api
經過 FileSystem API, Web 應用就能夠建立、讀取、導航用戶本地文件系統中的沙盒部分以及向其中寫入數據。
API 被分爲如下不一樣的主題:
FileSystem API 是非標準 API。在發佈環境因慎重使用,由於並是全部的瀏覽器都支持,實現方式可能存在很大的不兼容性,而且在未來可能也會發生變化。
網絡應用可經過調用 window.requestFileSystem()
請求對沙盒文件系統的訪問權限:
// Note: The file system has been prefixed as of Google Chrome 12: window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem; window.requestFileSystem(type, size, successCallback, opt_errorCallback)
type:文件存儲是否應該是持久的。可能的值包括 window.TEMPORARY
和 window.PERSISTENT
。經過 TEMPORARY 存儲的數據可由瀏覽器自行決定刪除(例如在須要更多空間的狀況下),要清除PERSISTENT 存儲,必須得到用戶或應用的明確受權,而且須要用戶向你的應用授予配額。
size: 應用須要用於存儲的大小 (以字節爲單位)。
successCallback:文件系統請求成功時調用的回調,其參數爲 FileSystem 對象。
opt_errorCallback: 用於處理錯誤或獲取文件系統的請求遭到拒絕時可選的回調,其參數爲 FileError 對象。
若是你是首次調用 requestFileSystem()
,系統會爲你的應用建立新的存儲。請注意,這是沙箱文件系統,也就是說,一個網絡應用沒法訪問另外一個應用的文件。
在訪問文件系統以後,能夠對文件和目錄執行大多數標準操做。
與其餘存儲類型相比,文件系統是一個徹底不一樣的存儲類型,由於它的旨在知足數據庫,很不能很好地服務的客戶端存儲用例。一般,這些應用程序處理大型二進制blob或與瀏覽器上下文以外的應用程序共享數據。
如下使用文件系統 API 的幾個示例:
有上傳的應用
視頻遊戲或其餘使用大量媒體資源的應用
音頻或照片編輯器使用線下訪問或本地緩存
線下視頻瀏覽
線下網絡郵件客戶端
目前瀏覽器對文件系統 API 的支持:
只讀的 localStorage 容許你訪問一個 Document 的遠端(origin)對象 Storage;其存儲的數據能在跨瀏覽器會話保留。 localStorage 相似 sessionStorage,其區別在於:存儲在 localStorage 的數據能夠長期保留;而當頁面會話結束——也就是說當頁面被關閉時,存儲在 sessionStorage 的數據會被清除 。
應注意不管數據存儲在 localStorage 仍是 sessionStorage ,它們都特定於頁面的協議。
另外,localStorage 中的鍵值對老是以字符串的形式存儲。
當前瀏覽器對API的支持:
sessionStorage 屬性容許你訪問一個 session Storage 對象。它與 localStorage 類似,不一樣之處在於 localStorage 裏面存儲的數據沒有過時時間設置,而存儲在 sessionStorage 裏面的數據在頁面會話結束時會被清除。頁面會話在瀏覽器打開期間一直保持,而且從新加載或恢復頁面仍會保持原來的頁面會話。在新標籤或窗口打開一個頁面時會在頂級瀏覽上下文中初始化一個新的會話,這點和 session cookies 的運行方式不一樣。
應該注意的是,不管是 localStorage 仍是 sessionStorage 中保存的數據都僅限於該頁面的協議。
當前瀏覽器對API的支持:
HTTP Cookie(也叫Web Cookie或瀏覽器Cookie)是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。一般,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持用戶的登陸狀態。Cookie 使基於無狀態的 HTTP 協議記錄穩定的狀態信息成爲了可能。
Cookie主要用於如下三個方面:
* 瀏覽器行爲跟蹤(如跟蹤分析用戶行爲等)
Cookie曾一度用於客戶端數據的存儲,因當時並無其它合適的存儲辦法而做爲惟一的存儲手段,但如今隨着現代瀏覽器開始支持各類各樣的存儲方式,Cookie漸漸被淘汰。因爲服務器指定Cookie後,瀏覽器的每次請求都會攜帶Cookie數據,會帶來額外的性能開銷(尤爲是在移動環境下)。
cookie 類型有兩種:
當機器處於不安全環境時,切記不能經過HTTP Cookie存儲、傳輸敏感信息,且全部瀏覽器都普遍支持cookie。
Cache 接口爲緩存的 Request/Response 對象對提供存儲機制,例如,做爲 ServiceWorker 生命週期的一部分。請注意,Cache 接口像 workers 同樣,是暴露在 window 做用域下的。儘管它被定義在 service worker 的標準中, 可是它沒必要必定要配合 service worker 使用.
一個域能夠有多個命名 Cache 對象。你須要在你的腳本 (例如,在 ServiceWorker 中)中處理緩存更新的方式。除非明確地更新緩存,不然緩存將不會被更新;除非刪除,不然緩存數據不會過時。使用 CacheStorage.open(cacheName) 打開一個Cache 對象,再使用 Cache 對象的方法去處理緩存.
你須要按期地清理緩存條目,由於每一個瀏覽器都硬性限制了一個域下緩存數據的大小。緩存配額使用估算值,可使用 StorageEstimate API 得到。瀏覽器盡其所能去管理磁盤空間,但它有可能刪除一個域下的緩存數據。瀏覽器要麼自動刪除特定域的所有緩存,要麼所有保留。確保按名稱安裝版本緩存,並僅從能夠安全操做的腳本版本中使用緩存。查看 Deleting old caches 獲取更多信息.
CacheStorage 接口表示 Cache 對象的存儲。
你能夠經過 caches 屬性訪問 CacheStorage .
IndexedDB 是一種在用戶瀏覽器中持久存儲數據的方法。由於它容許你建立具備豐富查詢功能的 Web 應用程序,不管網絡可用性如何,這些應用程序均可以在線和離線工做。IndexedDB 對於存儲大量數據的應用程序(例如,借出庫中的 DVD 目錄)和不須要持久 internet 鏈接才能工做的應用程序(例如,郵件客戶機、待辦事項列表和記事本)很是有用。
在本文中,會更詳細地討論存儲數據庫,由於其他的存儲 Api 都是衆所周知的。另外,隨着 Web 應用程序的複雜性愈來愈高,IndexedDB 也愈來愈受歡迎。
IndexedDB 經過「鍵」來存儲和檢索對象。對數據庫所作的全部更改都發生在事務中,像大多數 Web 存儲解決方案同樣,IndexedDB 遵循同源策略。所以,雖然能夠訪問域中存儲的數據,可是不能跨不一樣的域訪問數據。
IndexedDB 是一個 異步 API,能夠在大多數上下文中使用,包括 WebWorkers。它過去也包括一個同步版本,供 Web 開發者使用,可是因爲 Web 社區對它缺少興趣,因此從規範中刪除了這個版本。
IndexedDB 曾經有一個與之競爭的規範,稱爲 WebSQL 數據庫,可是 W3C 棄用了它。雖然 IndexedDB 和WebSQL 都是存儲解決方案,但它們提供的功能不一樣。WebSQL 數據庫是一個關係數據庫訪問系統,而IndexedDB 是一個索引表系統。
不要一開始就使用 IndexedDB,這依賴於你對其餘類型數據庫的假設。相反,應該仔細閱讀文檔,如下是一些須要牢記的基本概念:
onsuccess
和 onerror
事件屬性,同時你還對 「事件」 調用 addEventListener()
和 removeEventListener()
。「請求」 還包括 readyState
,result
和 errorCode
屬性,用來表示「請求」的狀態。result
屬性尤爲神奇,他能夠根據「請求」生成的方式變成不一樣的東西,例如:IDBCursor 實例、剛插入數據庫的數值對應的鍵值(key)等。如下狀況不適合使用IndexedDB
注意,在如下狀況下,數據庫可能被清除:
確切的環境和瀏覽器特性會隨着時間改變,但瀏覽器廠商一般會遵循盡最大努力保留數據的理念。
如前所述,最好選擇儘量多的瀏覽器普遍支持的 Api,並提供異步調用模型,以最大限度地提升 UI 響應能力。這些標準天然會致使如下技術選擇:
原文:
https://blog.sessionstack.com...
這篇主要一些內容原做者大部分是經過 MDN 整理的組合的,我也是根據中文的 MND 整理的組合。
你的點贊是我持續分享好東西的動力,歡迎點贊!