I have a file input : (jsbin)
<input type="file" accept="image/*" id="input" multiple onchange='handleFiles(this)' />
Which, when file selected, shows small images of the selected image:
I can do it in two ways :
using FileReader:
function handleFiles(t) //t=this
{
var fileList = t.files;
for (var i = 0; i < fileList.length; i++)
{
var file = fileList[i];
var img = document.createElement("img");
img.style... = ...
document.getElementById('body').appendChild(img);
var reader = new FileReader();
reader.onload = (function (aImg)
{
return function (e)
{
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
}
// ...
}
using ObjectURL / BLOB :
function handleFiles(t)
{
var fileList = t.files;
for (var i = 0; i < fileList.length; i++)
{
var file = fileList[i];
var img = document.createElement("img");
img.src = window.URL.createObjectURL(file);
img.onload = function (e)
{
window.URL.revokeObjectURL(this.src);
}
document.getElementById('body').appendChild(img);
}
}
As you can see , both work :
BUT
The html result is different :
Question :
With the first one, I already know what I can do, it's pure data-uri
data.
But when should I use the second approach (blob)?
I mean - what can I do blob:http%3A//run.jsbin.com/82b29cc5-8452-4ae2-80ca-a949898f4295
?
p.s.
mdn explanation about URL.createObjectURL
doesn't help me about when should I use each.
The length of a blob:
URL is always below a reasonable limit.
Data URLs can be arbitrary large. Consequently, when a data URL is too long, some browsers (IE, cough) will not display the image any more. So, if you want to display very large files, using blob:
(or filesystem:
URLs) might make more sense than data-URLs.
Also, you can directly recover data from a blob:
URL (provided that the blob has not been revoked yet, e.g. because the document was unloaded, and the same origin policy is not violated) using XMLHttpRequest
. For example, the following code gets the content of a blob URL as text:
var blobUrl = URL.createObjectURL(new Blob(['Test'], {type: 'text/plain'}));
var x = new XMLHttpRequest();
// set x.responseType = 'blob' if you want to get a Blob object:
// x.responseType = 'blob';
x.onload = function() {
alert(x.responseText);
};
x.open('get', blobUrl);
x.send();
If you want to submit the contents of a File to a server using XMLHttpRequest
, it doesn't really make sense to use a blob:
or data:
URL. Just submit the File
object directly using the FormData
object. If you lost the original File
reference, and you only have a blob:
URL, then you can use the previous snippet to get a Blob
object again for use in FormData
.
Given a data:
-URL, it is far from easy to recover the original data. Firefox and Opera 12- allow use of a data:
-URL in XMLHttpRequest
. Chrome, Internet Explorer, Safari and Opera 15+ refuse to load a data-URL via XMLHttpRequest. So, with respect to recovering data, blob:
URLs are also superior over data:
-URLs.
If you want to display the result of a File in a different frame on the same origin, definitely use a blob:
URL. If you want to manipulate data contained in a Blob
in a differerent frame (possibly on a different origin), do not use blob or data URLs, send the data directly using postMessage
.
blob:
-URLs are generally better than data:
-URLs for representing (binary) data. For small data (max 20kb), data:
URLs might be a better choice because of the higher range of supported browsers: Compare Can I use Blob URLs with Can I use Data URIs (though if you're writing a complex HTML5 application, odds are that you're not going to support IE9-).