<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端存儲除了 localStorage 還有啥

          共 9345字,需瀏覽 19分鐘

           ·

          2020-07-21 16:13

          前端的數(shù)據(jù)存儲方式,你除了用過 Cookies、localStorage 和 sessionStorage 外,還有用過其它的存儲方式么?其實除了前面提到的 3 種存儲方式,目前主流的瀏覽器還支持 Web SQL 和 IndexedDB。

          目前市場上主流的瀏覽器有 Chrome 、Safari、Firefox、Opera、UC Browser 和 Internet Explorer 等,其中截止 2020 年 5 月,Chrome 的市場占有率為?「63.93%」,遠(yuǎn)遠(yuǎn)超過第二名 Safari 瀏覽(「18.19%」)。

          f2f7436a80d248790fc6348f0880f659.webp

          (圖片來源:https://gs.statcounter.com/)

          這里我們以市場占有率第一的 Chrome 瀏覽器為例,來了解一下它支持的所有存儲方案:

          5a96478f6a147cd54122f562e38518d2.webp

          (打開 Chrome 開發(fā)者工具,切換至 Application 欄位)

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

          一、有趣好玩的開源庫

          1.1 Sharedb

          ?

          Realtime database backend based on Operational Transformation (OT)。

          https://github.com/share/sharedb

          ?

          ShareDB 是一個基于 JSON 文檔操作轉(zhuǎn)換(OT)的實時數(shù)據(jù)庫后端。它是 DerbyJS Web 應(yīng)用程序框架的實時后端。

          「示例1:實時數(shù)據(jù)同步」

          6e8b713bf0e95414431dee573083084b.webp

          「示例2:展示實時查詢的排行榜應(yīng)用程序」

          4ca261e5ca1ea50cf134a5e8f3191733.webp

          1.2 ImmortalDB

          ?

          ? A relentless key-value store for the browser。

          https://github.com/gruns/ImmortalDB

          ?

          ImmortalDB 是在瀏覽器中存儲持久鍵值數(shù)據(jù)的最佳方法。保存到 ImmortalDB 的數(shù)據(jù)被冗余地存儲在 Cookies,IndexedDB 和 ?localStorage 中,并且如果其中的任何數(shù)據(jù)被刪除或損壞,它們將不斷進(jìn)行自我修復(fù)。

          例如,清除 Cookie 是一種常見的用戶操作,即使對于非技術(shù)用戶也是如此。在存儲壓力下,瀏覽器在沒有警告的情況下隨意刪除 ? ?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 進(jìn)行了擴(kuò)展,添加了超時時間,序列化方法。

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

          ?

          WebStorageCache 對 HTML5 localStorage 和 sessionStorage 進(jìn)行了擴(kuò)展,「添加了超時時間,序列化方法」。可以直接存儲 JSON 對象,同時可以非常簡單的進(jìn)行超時時間的設(shè)置。

          ?

          優(yōu)化:WebStorageCache 自動清除訪問的過期數(shù)據(jù),避免了過期數(shù)據(jù)的累積。另外也提供了清除全部過期數(shù)據(jù)的方法: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對象,默認(rèn)使用序列化方法為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 中(尤其是在移動設(shè)備上)存儲大量數(shù)據(jù)的需求。localStorage 通常限制為 5MB ~10MB,你可以通過對數(shù)據(jù)進(jìn)行壓縮,以存儲更多的數(shù)據(jù)。

          「示例」

          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);

          下圖是使用官方在線示例進(jìn)行字符串壓縮測試的結(jié)果:

          35bdb5aadcc6d71d9b4e04ff7d69794b.webp

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

          接下來我們開始來介紹一些主流的數(shù)據(jù)庫。

          二、主流的數(shù)據(jù)庫

          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)),進(jìn)而改善你的 Web 應(yīng)用程序的離線體驗。

          對于不支持 IndexedDB 或 WebSQL 的瀏覽器,localForage 會使用 localStorage 進(jìn)行數(shù)據(jù)存儲。此外,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 23、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 是一個瀏覽器內(nèi)數(shù)據(jù)庫,允許應(yīng)用程序在本地保存數(shù)據(jù),以便用戶即使在離線時也可以享受應(yīng)用程序的所有功能。另外,數(shù)據(jù)在客戶端之間是同步的,因此用戶可以隨時隨地保持最新狀態(tài)。

          PouchDB 也在 Node.js 中運行,可以用作與?「CouchDB」?兼容的服務(wù)器的直接接口。該 API 在每個環(huán)境中工作都是相同的,因此你可以花更少的時間來擔(dān)心瀏覽器的差異,而花更多的時間來編寫干凈、一致的代碼。

          PouchDB 支持所有現(xiàn)代瀏覽器:

          • 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,若當(dāng)前環(huán)境不支持 IndexedDB 則回退到 Web SQL。

          2.3 Rxdb

          ?

          ? ? ? A realtime Database for JavaScript Applications.

          https://github.com/pubkey/rxdb

          ?

          RxDB(Reactive Database 的縮寫)是 NoSQL 數(shù)據(jù)庫,用于 JavaScript 應(yīng)用程序,如網(wǎng)站,混合應(yīng)用程序,Electron Apps,Progressive Web Apps 和 Node.js。響應(yīng)式意味著你不僅可以查詢當(dāng)前狀態(tài),還可以訂閱所有狀態(tài)更改,比如查詢的結(jié)果或文檔的單個字段。

          fb58ccb8cb2580803c1340e778cffb2d.webp

          這對于基于 UI 的實時應(yīng)用程序非常有用,因為它易于開發(fā),并且具有很大的性能優(yōu)勢。為了在客戶端和服務(wù)器之間復(fù)制數(shù)據(jù),RxDB 提供了用于與任何 CouchDB 兼容端點以及自定義 GraphQL 端點進(jìn)行實時復(fù)制的模塊。

          RxDB 支持以下特性:

          • Mango-Query:支持 mquery API 從集合中獲取數(shù)據(jù),支持鏈?zhǔn)降?mongoDB 查詢風(fēng)格。
          • Replication:因為 RxDB 依賴于 PouchDB,因此很容易實現(xiàn)終端設(shè)備與服務(wù)器之間的數(shù)據(jù)同步。
          • Reactive:RxDB 使得同步 DOM 的狀態(tài)變得很簡單。
          • MultiWindow/Tab:當(dāng) RxDB 的兩個實例使用相同的存儲引擎,它們的狀態(tài)和操作流將會被廣播。這意味著對于兩個瀏覽器窗口,窗口 #1 的數(shù)據(jù)變化也會自動影響窗口 #2 的數(shù)據(jù)狀態(tài)。
          • Schema:通過 jsonschema 來定義 Schemas,它們用來描述數(shù)據(jù)格式。
          • Encryption:通過將模式字段設(shè)置為encrypted,該字段的值將以加密模式存儲,沒有密碼就無法讀取。

          2.4 NeDB

          ?

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

          https://github.com/louischatriot/nedb

          ?

          NeDB 是一個 JavaScript 數(shù)據(jù)庫,能夠運行在 Node.js、nw.js、Electron 和瀏覽器環(huán)境。它是使用純的 JavaScript 實現(xiàn),不依賴其它庫,提供的 API 是 MongoDB API 的子集,重要的是它的速度非常快:

          • 插入:10,680 ops/s

          • 查找:43,290 ops/s

          • 更新:8,000 ops/s。

          • 刪除:11,750 ops/s。

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

          2.5 Dexie.js

          ?

          A Minimalistic Wrapper for IndexedDB.

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

          ?

          Dexie.js 是 IndexedDB 的包裝庫,它提供了一套經(jīng)過精心設(shè)計的 API,強(qiáng)大的錯誤處理,較強(qiáng)的可擴(kuò)展性,此外它能夠跟蹤數(shù)據(jù)變化,支持 KeyRange (搜索不區(qū)分大小寫,可設(shè)置匹方式和 OR 操作)。

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

          • 異常錯誤處理。
          • 較弱的查詢功能。
          • 代碼復(fù)雜性。

          為了便于開發(fā)者接入 Dexie.js,在 Dexie.js 官網(wǎng)中提供了豐富的示例:

          • 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 存儲方案。

          三、各種 Web 存儲方案簡介

          3.1 Cookie

          HTTP Cookie(也叫 Web Cookie 或瀏覽器 Cookie)是服務(wù)器發(fā)送到用戶瀏覽器并保存在本地的一小塊數(shù)據(jù),它會在瀏覽器下次向同一服務(wù)器再發(fā)起請求時被攜帶并發(fā)送到服務(wù)器上。通常,它用于告知服務(wù)端兩個請求是否來自同一瀏覽器,如保持用戶的登錄狀態(tài)。

          Cookie 主要用于以下三個方面:

          • 會話狀態(tài)管理(如用戶登錄狀態(tài)、購物車、游戲分?jǐn)?shù)或其它需要記錄的信息);
          • 個性化設(shè)置(如用戶自定義設(shè)置、主題等);
          • 瀏覽器行為跟蹤(如跟蹤分析用戶行為等)。

          Cookie 的特點:

          • Cookie 的大小受限,一般為 4 KB;
          • 同一個域名下存放 Cookie 的個數(shù)是有限制的,不同瀏覽器的個數(shù)不一樣,一般為 20 個;
          • Cookie 支持設(shè)置過期時間,當(dāng)過期時自動銷毀;
          • 每次發(fā)起同域下的 HTTP 請求時,都會攜帶當(dāng)前域名下的 Cookie;
          • 支持設(shè)置為?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

          一種持久化的存儲方式,也就是說如果不手動清除,數(shù)據(jù)就永遠(yuǎn)不會過期。它是采用鍵值對的方式存儲數(shù)據(jù),按域名將數(shù)據(jù)分別保存到對應(yīng)數(shù)據(jù)庫文件里。相比 Cookie 來說,它能保存更大的數(shù)據(jù)。

          localStorage 的特點:

          • 大小限制為 5MB ~10MB;
          • 在同源的所有標(biāo)簽頁和窗口之間共享數(shù)據(jù);
          • 數(shù)據(jù)僅保存在客戶端,不與服務(wù)器進(jìn)行通信;
          • 數(shù)據(jù)持久存在且不會過期,重啟瀏覽器后仍然存在;
          • 對數(shù)據(jù)的操作是同步的。

          「示例」

          //?通過setItem()增加一個數(shù)據(jù)項
          localStorage.setItem('myName',?'Semlinker');

          //?通過getItem()獲取某個數(shù)據(jù)項
          let?me?=?localStorage.getItem('myName');

          //?通過removeItem()移除某個數(shù)據(jù)項
          localStorage.removeItem('myName');

          //?移除所有數(shù)據(jù)項
          localStorage.clear();

          3.3 sessionStorage

          與服務(wù)端的 session 類似,sessionStorage 是一種會話級別的緩存,關(guān)閉瀏覽器時數(shù)據(jù)會被清除。需要注意的是 sessionStorage 的作用域是窗口級別的,也就是說不同窗口之間保存的 sessionStorage 數(shù)據(jù)是不能共享的。

          sessionStorage 的特點:

          • sessionStorage 的數(shù)據(jù)只存在于當(dāng)前瀏覽器的標(biāo)簽頁;
          • 數(shù)據(jù)在頁面刷新后依然存在,但在關(guān)閉瀏覽器標(biāo)簽頁之后數(shù)據(jù)就會被清除;
          • 與 localStorage 擁有統(tǒng)一的 API 接口;
          • 對數(shù)據(jù)的操作是同步的。

          「示例」

          //?通過setItem()增加一個數(shù)據(jù)項
          sessionStorage.setItem('myName',?'Semlinker');

          //?通過getItem()獲取某個數(shù)據(jù)項
          let?me?=?sessionStorage.getItem('myName');

          //?通過removeItem()移除某個數(shù)據(jù)項
          sessionStorage.removeItem('myName');

          //?移除所有數(shù)據(jù)項
          sessionStorage.clear();

          3.4 Web SQL

          Web SQL 數(shù)據(jù)庫 API 實際上不是 HTML5 規(guī)范的一部分,而是一個單獨的規(guī)范,它引入了一組 API 來使用 SQL 來操作客戶端數(shù)據(jù)庫。需要注意的是,HTML5 已經(jīng)放棄 Web SQL 數(shù)據(jù)庫。

          Web SQL Database 規(guī)范中定義的三個核心方法:

          • openDatabase:這個方法使用現(xiàn)有數(shù)據(jù)庫或新建數(shù)據(jù)庫來創(chuàng)建數(shù)據(jù)庫對象;

          • transaction:這個方法允許我們根據(jù)情況控制事務(wù)的提交或回滾;

          • executeSql:這個方法用于執(zhí)行真實的 SQL 語句。

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

          • Web SQL 能方便進(jìn)行對象存儲;
          • Web SQL 支持事務(wù),能方便地進(jìn)行數(shù)據(jù)查詢和數(shù)據(jù)處理操作。

          「示例」

          var?db?=?openDatabase('mydb',?'1.0',?'Test?DB',?2?*?1024?*?1024);

          db.transaction(function?(tx)?{?
          ???//?執(zhí)行查詢操作
          ???tx.executeSql('CREATE?TABLE?IF?NOT?EXISTS?LOGS?(id?unique,?log)');?
          ???//?執(zhí)行插入操作
          ???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,用于客戶端存儲大量結(jié)構(gòu)化數(shù)據(jù),包括文件、二進(jìn)制大型對象。該 API 使用索引來實現(xiàn)對該數(shù)據(jù)的高性能搜索。雖然 Web Storage 對于存儲較少量的數(shù)據(jù)很有用,但對于存儲更大量的結(jié)構(gòu)化數(shù)據(jù)來說,這種方法不太好用。IndexedDB 提供了一個解決方案。

          IndexedDB 的特點:

          • 存儲空間大:存儲空間可以達(dá)到幾百兆甚至更多;
          • 支持二進(jìn)制存儲:它不僅可以存儲字符串,而且還可以存儲二進(jìn)制數(shù)據(jù);
          • IndexedDB 有同源限制,每一個數(shù)據(jù)庫只能在自身域名下能訪問,不能跨域名訪問;
          • 支持事務(wù)型:IndexedDB 執(zhí)行的操作會按照事務(wù)來分組的,在一個事務(wù)中,要么所有的操作都成功,要么所有的操作都失敗;
          • 鍵值對存儲:IndexedDB 內(nèi)部采用對象倉庫(object store)存放數(shù)據(jù)。所有類型的數(shù)據(jù)都可以直接存入,包括 JavaScript 對象。對象倉庫中,數(shù)據(jù)以 “鍵值對” 的形式保存,每一個數(shù)據(jù)記錄都有對應(yīng)的主鍵,主鍵是獨一無二的,不能有重復(fù),否則會拋出一個錯誤。
          • 數(shù)據(jù)操作是異步的:使用 IndexedDB 執(zhí)行的操作是異步執(zhí)行的,以免阻塞應(yīng)用程序。

          「示例」

          var?dbName?=?"my_db";

          var?request?=?indexedDB.open(dbName,?2);

          request.onerror?=?function(event)?{
          ??//?錯誤處理
          };

          request.onupgradeneeded?=?function(event)?{
          ??var?db?=?event.target.result;

          ??//?建立一個對象倉庫來存儲我們客戶的相關(guān)信息,我們選擇?ssn?作為鍵路徑(key?path)
          ??//?因為?ssn?可以保證是不重復(fù)的
          ??var?objectStore?=?db.createObjectStore("customers",?{?keyPath:?"ssn"?});

          ??//?建立一個索引來通過姓名來搜索客戶。名字可能會重復(fù),所以我們不能使用 unique 索引
          ??objectStore.createIndex("name",?"name",?{?unique:?false?});

          ??//?使用郵箱建立索引,我們確保客戶的郵箱不會重復(fù),所以我們使用 unique 索引
          ??objectStore.createIndex("email",?"email",?{?unique:?true?});

          ??//?使用事務(wù)的?oncomplete?事件確保在插入數(shù)據(jù)前對象倉庫已經(jīng)創(chuàng)建完畢
          ??objectStore.transaction.oncomplete?=?function(event)?{
          ????//?將數(shù)據(jù)保存到新創(chuàng)建的對象倉庫
          ????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)等,如果你知道其它好玩的項目,歡迎給阿寶哥留言喲。

          四、參考資源

          • w3.org - webstorage
          • wiki - Web_storage



          - EOF -



          如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個小忙:


          1. 點個「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點在看,都是耍流氓 -_-)

          2. 關(guān)注我的官網(wǎng)?https://muyiy.cn,讓我們成為長期關(guān)系

          3. 關(guān)注公眾號「高級前端進(jìn)階」,公眾號后臺回復(fù)「面試題」 送你高級前端面試題,回復(fù)「加群」加入面試互助交流群



          》》面試官都在用的題庫,快來看看《《

          瀏覽 43
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕在线不卡 | 国产无码片 | 大鸡巴91 | 丁香 亚洲 | 日韩Aⅴ在线 |