Forked from robnyman/IndexedDB-storing-and-retrieving-files.js
Last active
April 4, 2021 22:10
-
-
Save tantaman/6921973 to your computer and use it in GitHub Desktop.
Download an image, save it to IndexedDB, read it out, display the image via createObjectURL - works in Chrome and Firefox. Based on https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/ but with fixes made for Chrome.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
// IndexedDB | |
function BrowserType() { | |
var n = navigator.appName; | |
var ua = navigator.userAgent; | |
var tem; | |
var m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i); | |
if (m && (tem = ua.match(/version\/([\.\d]+)/i)) != null) m[2] = tem[1]; | |
m = m ? [m[1], m[2]] : [n, navigator.appVersion, '-?']; | |
if ((m[0] == "Netscape") && ua.match(/rv:11/g)) { | |
m[0] = "MSIE"; | |
} | |
return { brand: m[0], version: m[1] }; | |
} | |
var browserName = BrowserType().brand; | |
console.log(browserName); | |
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.jpg", 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(); | |
}, | |
convertToBase64 = function(blob, cb) { | |
var fr = new FileReader(); | |
fr.onload = function(e) { | |
cb(e.target.result); | |
} | |
fr.readAsDataURL(blob); | |
}, | |
dataURLToBlob = function(dataURL) { | |
var BASE64_MARKER = ';base64,'; | |
if (dataURL.indexOf(BASE64_MARKER) == -1) { | |
var parts = dataURL.split(','); | |
var contentType = parts[0].split(':')[1]; | |
var raw = parts[1]; | |
return new Blob([raw], {type: contentType}); | |
} | |
var parts = dataURL.split(BASE64_MARKER); | |
var contentType = parts[0].split(':')[1]; | |
var raw = window.atob(parts[1]); | |
var rawLength = raw.length; | |
var uInt8Array = new Uint8Array(rawLength); | |
for (var i = 0; i < rawLength; ++i) { | |
uInt8Array[i] = raw.charCodeAt(i); | |
} | |
return new Blob([uInt8Array], {type: contentType}); | |
}, | |
putElephantInDb = function (blob) { | |
console.log("Putting elephants in IndexedDB"); | |
// Put the blob into the dabase | |
if (browserName == 'Chrome') { | |
// Chrome can't store blobs at the moment. | |
// Convert to base64. | |
convertToBase64(blob, continuation); | |
} else { | |
continuation(blob); | |
} | |
function continuation(blob) { | |
// Open a transaction to the database | |
var transaction = db.transaction(["elephants"], 'readwrite'); | |
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); | |
// we've received our image from the database. Convert it back to | |
// a blob if it is not a blob already. | |
if (browserName == 'Chrome') { | |
// Why conver to a blob instead of using the data url? | |
// because data URLs are huge and contain the entire image int he url. | |
// If you reference the same image multiple times | |
// with a data url you essentially | |
// end up with multiple copies of your image floating around. | |
// dataUrls also take up JS heap space. | |
imgFile = dataURLToBlob(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); | |
// localStorage.setItem('img', imgURL); | |
// window.open('blank.html'); | |
// 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); | |
}; | |
})(); |
// Chrome can't store blobs at the moment.
Is this still up to date?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm getting this error. Please helpp.
Uncaught ReadOnlyError: Failed to execute 'put' on 'IDBObjectStore': The transaction is read-only.