Хранение изображений и файлов с помощью HTML5 IndexDB

база данных внешний интерфейс JavaScript
Хранение изображений и файлов с помощью HTML5 IndexDB

Хранение изображений и файлов с помощью 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. Создайте хранилище объектов
  • 3. Получить файлы изображений в виде больших двоичных объектов
  • 4. Инициализировать транзакцию базы данных
  • 5. Сохраните большой двоичный объект изображения в базе данных.
  • 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, но скоро будет поддерживаться и в других веб-браузерах. Если веб-браузер не поддерживает это событие, вы можете использовать устаревший метод setVersion и подключиться к его событию onsuccess.

2. Создайте хранилище объектов (если оно еще не существует)

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

Здесь вы создаете ObjectStore, в котором будете хранить данные — или, в нашем случае, файлы — и после создания вам не нужно его воссоздавать, просто обновите его содержимое.

3. Получить файлы изображений в виде больших двоичных объектов

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

Этот код получает содержимое файла непосредственно в виде большого двоичного объекта. В настоящее время поддерживается только Firefox. Когда весь файл получен, большой двоичный объект отправляется функции для сохранения его в базе данных.

4. Инициализировать транзакцию базы данных


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

Чтобы начать запись в базу данных, вам нужно запустить транзакцию с именем objectStore и типом операции, которую вы хотите выполнить (в данном случае чтение и запись).

5. Сохраните большой двоичный объект изображения в базе данных.

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

Как только транзакция выполнена, вы получаете ссылку на желаемый объектный склад, затем помещаете в него свой большой двоичный объект и передаете ему ключ.

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

Исходный код на гитхабе