前端存儲之indexDB


 

在講indexDB之前,先簡單說說cookie、localStorage、sessionStorage。

cookie

Cookie 是小甜餅的意思。顧名思義,cookie 確實非常小,它的大小限制為4KB左右,是網景公司的前雇員 Lou Montulli 在1993年3月的發明。它的主要用途有保存登錄信息,比如你登錄某個網站市場可以看到“記住密碼”,這通常就是通過在 Cookie 中存入一段辨別用戶身份的數據來實現的。

localStorage

localStorage 是 HTML5 標准中新加入的技術,它並不是什么划時代的新東西。早在 IE 6 時代,就有一個叫 userData 的東西用於本地存儲,而當時考慮到瀏覽器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多數瀏覽器所支持,如果你的網站需要支持 IE6+,那以 userData 作為你的 polyfill 的方案是種不錯的選擇。

sessionStorage

sessionStorage 與 localStorage 的接口類似,但保存數據的生命周期與 localStorage 不同。 Session 這個詞的意思,直譯過來是“會話”。它只是可以將一部分數據在當前會話中保存下來,刷新頁面數據依舊存在。但當頁面關閉后,sessionStorage 中的數據就會被清空。

Desktop Chrome Edge Firefox Internet Explorer Opera Safari
localStorage 4 Yes 3.5 8 10.5 4
sessionStorage 5 Yes 2 8 10.5 4
Mobile Android webview Chrome for Android Edge Mobile Firefox for Android Opera for Android iOS Safari
localStorage Yes Yes Yes Yes 10.5 3.2
sessionStorage Yes Yes Yes Yes 11 3.2

cookie、localStorage、sessionStorage異同

特性 Cookie localStorage sessionStorage
數據的生命期 一般由服務器生成,可設置失效時間。如果在瀏覽器端生成Cookie,默認是關閉瀏覽器后失效 除非被清除,否則永久保存 僅在當前會話下有效,關閉頁面或瀏覽器后被清除
存放數據大小 4K左右 一般為5MB 一般為5MB
與服務器端通信 每次都會攜帶在HTTP頭中,如果使用cookie保存過多數據會帶來性能問題 僅在客戶端(即瀏覽器)中保存,不參與和服務器的通信 僅在客戶端(即瀏覽器)中保存,不參與和服務器的通信
易用性 需要程序員自己封裝,源生的Cookie接口不友好 源生接口可以接受,亦可再次封裝來對Object和Array有更好的支持 源生接口可以接受,亦可再次封裝來對Object和Array有更好的支持

接下來就開始上重頭戲了 —— indexDB

indexDB

隨着瀏覽器的功能不斷增強,越來越多的網站開始考慮,將大量數據儲存在客戶端,這樣可以減少從服務器獲取數據,直接從本地獲取數據。

通俗地講,IndexedDB 就是瀏覽器提供的本地數據庫,它可以被網頁腳本創建和操作。IndexedDB 允許儲存大量數據,提供查找接口,還能建立索引。這些都是 LocalStorage 所不具備的。就數據庫類型而言,IndexedDB 不屬於關系型數據庫(不支持 SQL 查詢語句),更接近 NoSQL 數據庫。

操作步驟

查看更多信息參考

  • 創建/打開數據庫。
  • 在數據庫中創建一個對象倉庫(object store)。
  • 啟動一個事務,並發送一個請求來執行一些數據庫操作,像增加或提取數據等。
  • 通過監聽正確類型的 DOM 事件以等待操作完成。
  • 在操作結果上進行一些操作(可以在 request 對象中找到)

打開數據庫

var db = null; var request = window.indexedDB.open("MyTestDatabase"); request.onerror = function(event) { // 錯誤處理 console.log(' 打開數據庫報錯'); }; request.onsuccess = function(event) { // 成功處理 db = event.target.result; console.log('打開數據庫成功'); }; 

創建和更新數據庫版本號

如果指定的版本號,大於數據庫的實際版本號,就會發生數據庫升級事件upgradeneeded。這時通過事件對象的target.result屬性,拿到數據庫實例。

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

新建數據庫

新建數據庫與打開數據庫是同一個操作。如果指定的數據庫不存在,就會新建。不同之處在於,后續的操作主要在upgradeneeded事件的監聽函數里面完成,因為這時版本從無到有,所以會觸發這個事件。

通常,新建數據庫以后,第一件事是新建對象倉庫(即新建表)。

request.onupgradeneeded = function(event) { db = event.target.result; var objectStore = null; if (!db.objectStoreNames.contains('imgLists')) { objectStore = db.createObjectStore('imgLists', { keyPath: 'id' }); // unique name可能會重復 objectStore.createIndex('name', 'name', { unique: false }); } } 

創建一張叫imgLists的表格,主鍵是id。

寫入數據

新增數據指的是向對象倉庫寫入數據記錄。這需要通過事務完成。

// new 一個blob對象 var obj1 = {hello: "world"}; var blob = new Blob([JSON.stringify(obj1, null, 2)], {type : 'application/json'}); function add() { var request = db.transaction(['imgLists'], 'readwrite') .objectStore('imgLists') .add({ id: 1, name: '圖片1', path: '/static/image', blob: blob}); request.onsuccess = function (event) { console.log('數據寫入成功'); }; request.onerror = function (event) { console.log('數據寫入失敗'); } } 

查詢數據

查詢數據也是通過事物完成。

function read() { var transaction = db.transaction(['imgLists']); var objectStore = transaction.objectStore('imgLists'); // 用戶讀取數據,參數是主鍵 var request = objectStore.get(1); request.onerror = function(event) { console.log('事務失敗'); }; request.onsuccess = function( event) { if (request.result) { console.log(request.result); } else { console.log('未獲得數據記錄'); } }; } 

遍歷數據

遍歷數據表格的所有記錄,要使用指針對象 IDBCursor。

function readAll() { var objectStore = db.transaction('imgLists').objectStore('imgLists'); objectStore.openCursor().onsuccess = function (event) { var cursor = event.target.result; if (cursor) { console.log(cursor); cursor.continue(); } else { console.log('沒有更多數據了!'); } }; } 

更新數據

function update() { var request = db.transaction(['imgLists'], 'readwrite') .objectStore('imgLists') // 主動更新主鍵為1 .put({ id: 1, name: '圖片2', path: '/static/image2'}); request.onsuccess = function (event) { console.log('數據更新成功'); }; request.onerror = function (event) { console.log('數據更新失敗'); } } 

刪除數據

function remove() { var request = db.transaction(['imgLists'], 'readwrite') .objectStore('imgLists') .delete(1); request.onsuccess = function (event) { console.log('數據刪除成功'); }; } remove(); 

創建/使用索引

索引的意義在於,可以讓你搜索任意字段,也就是說從任意字段拿到數據記錄。如果不建立索引,默認只能搜索主鍵(即從主鍵取值)。

    objectStore.createIndex('name', 'name', { unique: false });
    function findIndex() { var transaction = db.transaction(['imgLists'], 'readonly'); var store = transaction.objectStore('imgLists'); var index = store.index('name'); var request = index.get('圖片1'); request.onsuccess = function (e) { var result = e.target.result; if (result) { console.log(result); } else { // ... } } } 

使用場景

indexDB是一個瀏覽器使用簡易的數據庫。隨着前端功能復雜度提升,用戶需要多元化,前端indexDB應用也就越來越多。桌面應用、Progressive Web App(PWA)、chrome擴展組件的開發等。用戶同時會獲取/操作更多的信息,怎么留存這些大量的數據,那么我們的indexDB就上線了。案例:DevDocs,electron開發的桌面應用(圖片傳輸)。

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM