前端存儲除了 localStorage 還有啥

本文介紹一些與前端數據存儲有關,有趣、好玩、有用的開源庫。除此以外,還會讓你掌握各類 Web 存儲方案的特色,趕忙來了解一下。html

在介紹目前比較流行的一些開源的前端存儲方案以前,阿寶哥先分享一些與存儲有關,有趣好玩的開源庫。前端

閱讀阿寶哥上週熱門文章(感謝掘友的鼓勵與支持🌹🌹🌹):git

1、有趣好玩的開源庫

1.1 Sharedb

Realtime database backend based on Operational Transformation (OT)。github

https://github.com/share/sharedbweb

ShareDB 是一個基於 JSON 文檔操做轉換(OT)的實時數據庫後端。它是 DerbyJS Web 應用程序框架的實時後端。typescript

示例1:實時數據同步數據庫

示例2:展現實時查詢的排行榜應用程序json

1.2 ImmortalDB

🔩 A relentless key-value store for the browser。後端

https://github.com/gruns/ImmortalDB跨域

ImmortalDB 是在瀏覽器中存儲持久鍵值數據的最佳方法。保存到 ImmortalDB 的數據被冗餘地存儲在 Cookies,IndexedDB 和 localStorage 中,而且若是其中的任何數據被刪除或損壞,它們將不斷進行自我修復。

例如,清除 Cookie 是一種常見的用戶操做,即便對於非技術用戶也是如此。在存儲壓力下,瀏覽器在沒有警告的狀況下隨意刪除 IndexedDB、localStorage 或 sessionStorage。

示例

import { ImmortalDB } from 'immortal-db'
 await ImmortalDB.set('name', 'semlinker'); // Set await ImmortalDB.get('name', default='lolo'); // Get await ImmortalDB.remove('name'); // Remove  複製代碼

1.3 web-storage-cache

對 localStorage 和 sessionStorage 進行了擴展,添加了超時時間,序列化方法。

https://github.com/wuchangming/web-storage-cache

WebStorageCache 對 HTML5 localStorage 和 sessionStorage 進行了擴展,添加了超時時間,序列化方法。能夠直接存儲 JSON 對象,同時能夠很是簡單的進行超時時間的設置。

優化:WebStorageCache 自動清除訪問的過時數據,避免了過時數據的累積。另外也提供了清除所有過時數據的方法:wsCache.deleteAllExpires();

示例

var wsCache = new WebStorageCache();
 // 緩存字符串'wqteam' 到 'username' 中, 超時時間100秒 wsCache.set('username', 'wqteam', {exp : 100});  // 超時截止日期,可用使用Date類型 var nextYear = new Date(); nextYear.setFullYear(nextYear.getFullYear() + 1); wsCache.set('username', 'wqteam', {exp : nextYear});  // 獲取緩存中 'username' 的值 wsCache.get('username');  // 緩存簡單js對象,默認使用序列化方法爲JSON.stringify。 // 能夠經過初始化wsCache的時候配置serializer.serialize wsCache.set('user', { name: 'Wu', organization: 'wqteam'}); 複製代碼

1.4 lz-string

LZ-based compression algorithm for JavaScript。

https://github.com/pieroxy/lz-string/

lz-string 旨在知足在 localStorage 中(尤爲是在移動設備上)存儲大量數據的需求。 localStorage 一般限制爲 5MB ~10MB,你能夠經過對數據進行壓縮,以存儲更多的數據。

示例

var string = "Hello, my name is semlinker";
console.log("Size of sample is: " + string.length);  var compressed = LZString.compress(string); console.log("Size of compressed sample is: " + compressed.length);  string = LZString.decompress(compressed); console.log("Sample is: " + string); 複製代碼

下圖是使用官方在線示例進行字符串壓縮測試的結果:

(圖片來源:https://pieroxy.net/blog/pages/lz-string/demo.html)

接下來咱們開始來介紹一些主流的數據庫。

2、主流的數據庫

2.1 localForage

💾 Offline storage, improved. Wraps IndexedDB, WebSQL, or localStorage using a simple but powerful API.

https://github.com/localForage/localForage

localForage 是一個快速簡單的 JavaScript 存儲庫。 它經過使用相似於 localStorage 的簡單 API 來使用異步存儲(IndexedDB 或 WebSQL)),進而改善你的 Web 應用程序的離線體驗。

對於不支持 IndexedDB 或 WebSQL 的瀏覽器,localForage 會使用 localStorage 進行數據存儲。此外,localForage 還支持存儲全部能夠序列化爲 JSON 的原生 JS 對象以及 ArrayBuffers,Blob 和 TypedArrays。

localForage 主要支持的平臺:

  • IE 10(IE 8+ 使用 localStorage)
  • Opera 15(Opera 10.5+ 使用 localStorage)
  • Firefox 18
  • Safari 3.1(包括 Mobile Safari)
  • Chrome 2三、Chrome for Android 32
  • Phonegap/Apache Cordova 1.2.0

2.2 PouchDB

🐨 - PouchDB is a pocket-sized database.

https://github.com/pouchdb/pouchdb

PouchDB 是一個瀏覽器內數據庫,容許應用程序在本地保存數據,以便用戶即便在離線時也能夠享受應用程序的全部功能。另外,數據在客戶端之間是同步的,所以用戶能夠隨時隨地保持最新狀態。

PouchDB 也在 Node.js 中運行,能夠用做與 CouchDB 兼容的服務器的直接接口。該 API 在每一個環境中工做都是相同的,所以你能夠花更少的時間來擔憂瀏覽器的差別,而花更多的時間來編寫乾淨、一致的代碼。

PouchDB 支持全部現代瀏覽器:

  • Firefox 29+ (Including Firefox OS and Firefox for Android)
  • Chrome 30+
  • Safari 5+
  • Internet Explorer 10+
  • Opera 21+
  • Android 4.0+
  • iOS 7.1+
  • Windows Phone 8+

PouchDB 在幕後使用 IndexedDB,若當前環境不支持 IndexedDB 則回退到 Web SQL。

2.3 Rxdb

💻 🔄 📱 A realtime Database for JavaScript Applications.

https://github.com/pubkey/rxdb

RxDB(Reactive Database 的縮寫)是 NoSQL 數據庫,用於 JavaScript 應用程序,如網站,混合應用程序,Electron Apps,Progressive Web Apps 和 Node.js。響應式意味着你不只能夠查詢當前狀態,還能夠訂閱全部狀態更改,好比查詢的結果或文檔的單個字段。

這對於基於 UI 的實時應用程序很是有用,由於它易於開發,而且具備很大的性能優點。爲了在客戶端和服務器之間複製數據,RxDB 提供了用於與任何 CouchDB 兼容端點以及自定義 GraphQL 端點進行實時複製的模塊。

RxDB 支持如下特性:

  • Mango-Query:支持 mquery API 從集合中獲取數據,支持鏈式的 mongoDB 查詢風格。
  • Replication:由於 RxDB 依賴於 PouchDB,所以很容易實現終端設備與服務器之間的數據同步。
  • Reactive:RxDB 使得同步 DOM 的狀態變得很簡單。
  • MultiWindow/Tab:當 RxDB 的兩個實例使用相同的存儲引擎,它們的狀態和操做流將會被廣播。這意味着對於兩個瀏覽器窗口,窗口 #1 的數據變化也會自動影響窗口 #2 的數據狀態。
  • Schema:經過 jsonschema 來定義 Schemas,它們用來描述數據格式。
  • Encryption:經過將模式字段設置爲encrypted,該字段的值將以加密模式存儲,沒有密碼就沒法讀取。

2.4 NeDB

The JavaScript Database, for Node.js, nw.js, electron and the browser.

https://github.com/louischatriot/nedb

NeDB 是一個 JavaScript 數據庫,可以運行在 Node.js、nw.js、Electron 和瀏覽器環境。它是使用純的 JavaScript 實現,不依賴其它庫,提供的 API 是 MongoDB API 的子集,重要的是它的速度很是快:

  • 插入:10,680 ops/s

  • 查找:43,290 ops/s

  • 更新:8,000 ops/s。

  • 刪除:11,750 ops/s。

ops (operation per second) 即表示每秒操做的次數。

2.5 Dexie.js

A Minimalistic Wrapper for IndexedDB.

https://github.com/dfahlander/Dexie.js

Dexie.js 是 IndexedDB 的包裝庫,它提供了一套通過精心設計的 API,強大的錯誤處理,較強的可擴展性,此外它可以跟蹤數據變化,支持 KeyRange (搜索不區分大小寫,可設置匹方式和 OR 操做)。

Dexie.js 主要爲了解決原生 IndexedDB API 中存在的三個主要問題:

  • 異常錯誤處理。
  • 較弱的查詢功能。
  • 代碼複雜性。

爲了便於開發者接入 Dexie.js,在 Dexie.js 官網中提供了豐富的示例:

  • React + Dexie
  • React + Redux + Dexie
  • Dexie with Typescript
  • Angular + Dexie
  • Dexie with Electron
  • Full Text Search

以上只列出部分示例,瞭解更多示例請訪問:Dexie.js - Samples(https://dexie.org/docs/Samples)。最後咱們來簡單介紹一下各類 Web 存儲方案。

3、各類 Web 存儲方案簡介

3.1 Cookie

HTTP Cookie(也叫 Web Cookie 或瀏覽器 Cookie)是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。一般,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持用戶的登陸狀態。

Cookie 主要用於如下三個方面:

  • 會話狀態管理(如用戶登陸狀態、購物車、遊戲分數或其它須要記錄的信息);
  • 個性化設置(如用戶自定義設置、主題等);
  • 瀏覽器行爲跟蹤(如跟蹤分析用戶行爲等)。

Cookie 的特色:

  • Cookie 的大小受限,通常爲 4 KB;
  • 同一個域名下存放 Cookie 的個數是有限制的,不一樣瀏覽器的個數不同,通常爲 20 個;
  • Cookie 支持設置過時時間,當過時時自動銷燬;
  • 每次發起同域下的 HTTP 請求時,都會攜帶當前域名下的 Cookie;
  • 支持設置爲 HttpOnly,防止 Cookie 被客戶端的 JavaScript 訪問。

示例1:簡單用法

document.cookie = "name=semlinker";
document.cookie = "favorite_food=tripe";  alert(document.cookie); // 顯示: name=semlinker;favorite_food=tripe 複製代碼

示例2:獲得名爲 test2 的 cookie

document.cookie = "test1=Hello";
document.cookie = "test2=World";  var myCookie = document.cookie  .replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1"); alert(myCookie); 複製代碼

3.2 localStorage

一種持久化的存儲方式,也就是說若是不手動清除,數據就永遠不會過時。它是採用鍵值對的方式存儲數據,按域名將數據分別保存到對應數據庫文件裏。相比 Cookie 來講,它能保存更大的數據。

localStorage 的特色:

  • 大小限制爲 5MB ~10MB;
  • 在同源的全部標籤頁和窗口之間共享數據;
  • 數據僅保存在客戶端,不與服務器進行通訊;
  • 數據持久存在且不會過時,重啓瀏覽器後仍然存在;
  • 對數據的操做是同步的。

示例

// 經過setItem()增長一個數據項
localStorage.setItem('myName', 'Semlinker');  // 經過getItem()獲取某個數據項 let me = localStorage.getItem('myName');  // 經過removeItem()移除某個數據項 localStorage.removeItem('myName');  // 移除全部數據項 localStorage.clear(); 複製代碼

3.3 sessionStorage

與服務端的 session 相似,sessionStorage 是一種會話級別的緩存,關閉瀏覽器時數據會被清除。須要注意的是 sessionStorage 的做用域是窗口級別的,也就是說不一樣窗口之間保存的 sessionStorage 數據是不能共享的。

sessionStorage 的特色:

  • sessionStorage 的數據只存在於當前瀏覽器的標籤頁;
  • 數據在頁面刷新後依然存在,但在關閉瀏覽器標籤頁以後數據就會被清除;
  • 與 localStorage 擁有統一的 API 接口;
  • 對數據的操做是同步的。

示例

// 經過setItem()增長一個數據項
sessionStorage.setItem('myName', 'Semlinker');  // 經過getItem()獲取某個數據項 let me = sessionStorage.getItem('myName');  // 經過removeItem()移除某個數據項 sessionStorage.removeItem('myName');  // 移除全部數據項 sessionStorage.clear(); 複製代碼

3.4 Web SQL

Web SQL 數據庫 API 實際上不是 HTML5 規範的一部分,而是一個單獨的規範,它引入了一組 API 來使用 SQL 來操做客戶端數據庫。須要注意的是,HTML5 已經放棄 Web SQL 數據庫。

Web SQL Database 規範中定義的三個核心方法:

  • openDatabase:這個方法使用現有數據庫或新建數據庫來建立數據庫對象;

  • transaction:這個方法容許咱們根據狀況控制事務的提交或回滾;

  • executeSql:這個方法用於執行真實的 SQL 語句。

Web SQL 的特色(相比 Cookie、localStorage 與 sessionStorage):

  • Web SQL 能方便進行對象存儲;
  • Web SQL 支持事務,能方便地進行數據查詢和數據處理操做。

示例

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
 db.transaction(function (tx) {  // 執行查詢操做  tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log)');  // 執行插入操做  tx.executeSql('INSERT INTO LOGS (id, log) VALUES (1, "foobar")');  tx.executeSql('INSERT INTO LOGS (id, log) VALUES (2, "logmsg")'); }); 複製代碼

3.5 IndexedDB

IndexedDB 是一種底層 API,用於客戶端存儲大量結構化數據,包括文件、二進制大型對象。該 API 使用索引來實現對該數據的高性能搜索。雖然 Web Storage 對於存儲較少許的數據頗有用,但對於存儲更大量的結構化數據來講,這種方法不太好用。IndexedDB 提供了一個解決方案。

IndexedDB 的特色:

  • 存儲空間大:存儲空間能夠達到幾百兆甚至更多;
  • 支持二進制存儲:它不只能夠存儲字符串,並且還能夠存儲二進制數據;
  • IndexedDB 有同源限制,每個數據庫只能在自身域名下能訪問,不能跨域名訪問;
  • 支持事務型:IndexedDB 執行的操做會按照事務來分組的,在一個事務中,要麼全部的操做都成功,要麼全部的操做都失敗;
  • 鍵值對存儲:IndexedDB 內部採用對象倉庫(object store)存放數據。全部類型的數據均可以直接存入,包括 JavaScript 對象。對象倉庫中,數據以 「鍵值對」 的形式保存,每個數據記錄都有對應的主鍵,主鍵是獨一無二的,不能有重複,不然會拋出一個錯誤。
  • 數據操做是異步的:使用 IndexedDB 執行的操做是異步執行的,以避免阻塞應用程序。

示例

var dbName = "my_db";
 var request = indexedDB.open(dbName, 2);  request.onerror = function(event) {  // 錯誤處理 };  request.onupgradeneeded = function(event) {  var db = event.target.result;   // 創建一個對象倉庫來存儲咱們客戶的相關信息,咱們選擇 ssn 做爲鍵路徑(key path)  // 由於 ssn 能夠保證是不重複的  var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });   // 創建一個索引來經過姓名來搜索客戶。名字可能會重複,因此咱們不能使用 unique 索引  objectStore.createIndex("name", "name", { unique: false });   // 使用郵箱創建索引,咱們確保客戶的郵箱不會重複,因此咱們使用 unique 索引  objectStore.createIndex("email", "email", { unique: true });   // 使用事務的 oncomplete 事件確保在插入數據前對象倉庫已經建立完畢  objectStore.transaction.oncomplete = function(event) {  // 將數據保存到新建立的對象倉庫  var customerObjectStore = db.transaction("customers", "readwrite").objectStore("customers");  customerData.forEach(function(customer) {  customerObjectStore.add(customer);  });  }; }; 複製代碼

篇幅有限這裏咱們只介紹了部分開源庫,其實還有一些其它成熟的開源庫,好比 lowdb(Local JSON Database)、Lovefield(Relational Database)和 LokiJS(NoSQL Database)等,若是你知道其它好玩的項目,歡迎給阿寶哥留言喲。

4、參考資源

建立了一個 「全棧修仙之路交流羣」 的微信羣,想加羣的小夥伴,加我微信 "semlinker",備註 TS。阿里、京東、騰訊的大佬都在羣裏等你喲。 semlinker/awesome-typescript 1.6K

本文使用 mdnice 排版

相關文章
相關標籤/搜索