使用HTML5 IndexDB儲存影象和檔案

一兵發表於2018-11-03

使用IndexedDB儲存影象和檔案

有一天,我們寫了關於如何在localStorage中儲存影象和檔案的文章,它是關於我們今天可用的實用主義。 然而,localStorage有一些效能影響 - 我們將在稍後的部落格中討論這個問題 - 並且未來期望的方法是使用IndexedDB。 在這裡,我將向您介紹如何在IndexedDB中儲存影象和檔案,然後通過ObjectURL呈現它們。

本文是翻譯過來的,原文在這裡Storing images and files in IndexedDB

關於作者: Robert Nyman [Editor emeritus]

Technical Evangelist & Editor of Mozilla Hacks. Gives talks & blogs about HTML5, JavaScript & the Open Web. Robert is a strong believer in HTML5 and the Open Web and has been working since 1999 with Front End development for the web - in Sweden and in New York City. He regularly also blogs at robertnyman.com and loves to travel and meet people.

使用IndexedDB儲存影象和檔案的常規步驟

首先,我們來談談我們將建立一個IndexedDB資料庫,將檔案儲存到其中然後將其讀出並顯示在頁面中的步驟:

  • 1、建立或開啟資料庫
  • 2、建立一個objectStore
  • 3、將影象檔案檢索為blob
  • 4、初始化一個資料庫事物
  • 5、儲存影象blob到資料庫中去
  • 6、讀出儲存的檔案並從中建立ObjectURL並將其設定為頁面中影象元素的src

1、建立或開啟資料庫。


// IndexedDB
window.indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
    IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
    dbVersion = 1;

/* 
    Note: The recommended way to do this is assigning it to window.indexedDB,
    to avoid potential issues in the global scope when web browsers start 
    removing prefixes in their implementations.
    You can assign it to a varible, like var indexedDB… but then you have 
    to make sure that the code is contained within a function.
*/

// Create/open database
var request = indexedDB.open("elephantFiles", dbVersion);

request.onsuccess = function (event) {
    console.log("Success creating/accessing IndexedDB database");
    db = request.result;

    db.onerror = function (event) {
        console.log("Error creating/accessing IndexedDB database");
    };
    
    // Interim solution for Google Chrome to create an objectStore. Will be deprecated
    if (db.setVersion) {
        if (db.version != dbVersion) {
            var setVersion = db.setVersion(dbVersion);
            setVersion.onsuccess = function () {
                createObjectStore(db);
                getImageFile();
            };
        }
        else {
            getImageFile();
        }
    }
    else {
        getImageFile();
    }
}

// For future use. Currently only in latest Firefox versions
request.onupgradeneeded = function (event) {
    createObjectStore(event.target.result);
};
複製程式碼

使用它的預期方法是在建立資料庫時觸發onupgradeneeded事件或獲取更高版本號。 目前僅在Firefox中支援此功能,但很快將在其他Web瀏覽器中支援。 如果Web瀏覽器不支援此事件,則可以使用已棄用的setVersion方法並連線到其onsuccess事件。

2、建立一個objectStore(如果它尚不存在)

// Create an objectStore
console.log("Creating objectStore")
dataBase.createObjectStore("elephants");

複製程式碼

在這裡,您建立一個ObjectStore,您將儲存資料 - 或者在我們的例子中,檔案 - 並且一旦建立,您不需要重新建立它,只需更新其內容即可。

3、將影象檔案檢索為blob

// Create XHR
var xhr = new XMLHttpRequest(),
    blob;

xhr.open("GET", "elephant.png", true);
// Set the responseType to blob
xhr.responseType = "blob";

xhr.addEventListener("load", function () {
    if (xhr.status === 200) {
        console.log("Image retrieved");
        
        // File as response
        blob = xhr.response;

        // Put the received blob into IndexedDB
        putElephantInDb(blob);
    }
}, false);
// Send XHR
xhr.send();
複製程式碼

此程式碼直接將檔案的內容作為blob獲取。目前只支援Firefox。 收到整個檔案後,將blob傳送到函式以將其儲存在資料庫中。

4、初始化一個資料庫事物


// Open a transaction to the database
var transaction = db.transaction(["elephants"], IDBTransaction.READ_WRITE);

複製程式碼

要開始向資料庫寫入內容,您需要使用objectStore名稱和要執行的操作型別(在本例中為read和write)啟動事務。

5、儲存影象blob到資料庫中去

// Put the blob into the dabase
transaction.objectStore("elephants").put(blob, "image");

複製程式碼

一旦事務到位,您將獲得對所需objectStore的引用,然後將您的blob放入其中併為其提供金鑰。

6、讀出儲存的檔案並從中建立ObjectURL並將其設定為頁面中影象元素的src

// Retrieve the file that was just stored
transaction.objectStore("elephants").get("image").onsuccess = function (event) {
    var imgFile = event.target.result;
    console.log("Got elephant!" + imgFile);

    // Get window.URL object
    var URL = window.URL || window.webkitURL;

    // Create and revoke ObjectURL
    var imgURL = URL.createObjectURL(imgFile);

    // Set img src to ObjectURL
    var imgElephant = document.getElementById("elephant");
    imgElephant.setAttribute("src", imgURL);

    // Revoking ObjectURL
    URL.revokeObjectURL(imgURL);
};
複製程式碼

使用相同的事務來獲取剛剛儲存的影象檔案,然後建立一個objectURL並將其設定為頁面中影象的src。 例如,這也可以是一個附加到指令碼元素的JavaScript檔案,然後它將解析JavaScript。

最後完整程式碼

(function () {
    // IndexedDB
    var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.OIndexedDB || window.msIndexedDB,
        IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.OIDBTransaction || window.msIDBTransaction,
        dbVersion = 1.0;

    // Create/open database
    var request = indexedDB.open("elephantFiles", dbVersion),
        db,
        createObjectStore = function (dataBase) {
            // Create an objectStore
            console.log("Creating objectStore")
            dataBase.createObjectStore("elephants");
        },

        getImageFile = function () {
            // Create XHR
            var xhr = new XMLHttpRequest(),
                blob;

            xhr.open("GET", "elephant.png", true);
            // Set the responseType to blob
            xhr.responseType = "blob";

            xhr.addEventListener("load", function () {
                if (xhr.status === 200) {
                    console.log("Image retrieved");
                    
                    // Blob as response
                    blob = xhr.response;
                    console.log("Blob:" + blob);

                    // Put the received blob into IndexedDB
                    putElephantInDb(blob);
                }
            }, false);
            // Send XHR
            xhr.send();
        },

        putElephantInDb = function (blob) {
            console.log("Putting elephants in IndexedDB");

            // Open a transaction to the database
            var transaction = db.transaction(["elephants"], IDBTransaction.READ_WRITE);

            // Put the blob into the dabase
            var put = transaction.objectStore("elephants").put(blob, "image");

            // Retrieve the file that was just stored
            transaction.objectStore("elephants").get("image").onsuccess = function (event) {
                var imgFile = event.target.result;
                console.log("Got elephant!" + imgFile);

                // Get window.URL object
                var URL = window.URL || window.webkitURL;

                // Create and revoke ObjectURL
                var imgURL = URL.createObjectURL(imgFile);

                // Set img src to ObjectURL
                var imgElephant = document.getElementById("elephant");
                imgElephant.setAttribute("src", imgURL);

                // Revoking ObjectURL
                URL.revokeObjectURL(imgURL);
            };
        };

    request.onerror = function (event) {
        console.log("Error creating/accessing IndexedDB database");
    };

    request.onsuccess = function (event) {
        console.log("Success creating/accessing IndexedDB database");
        db = request.result;

        db.onerror = function (event) {
            console.log("Error creating/accessing IndexedDB database");
        };
        
        // Interim solution for Google Chrome to create an objectStore. Will be deprecated
        if (db.setVersion) {
            if (db.version != dbVersion) {
                var setVersion = db.setVersion(dbVersion);
                setVersion.onsuccess = function () {
                    createObjectStore(db);
                    getImageFile();
                };
            }
            else {
                getImageFile();
            }
        }
        else {
            getImageFile();
        }
    }
    
    // For future use. Currently only in latest Firefox versions
    request.onupgradeneeded = function (event) {
        createObjectStore(event.target.result);
    };
})();


複製程式碼

瀏覽器支援

image

image

Github原始碼

相關文章