Using FileReader
's readAsDataURL()
I can transform arbitrary data into a Data URL. Is there way to convert a Data URL back into a Blob
instance using builtin browser apis?

- 7,550
- 4
- 29
- 37
10 Answers
User Matt has proposed the following code a year ago ( How to convert dataURL to file object in javascript? ) which might help you
EDIT: As some commenters reported, BlobBuilder has been deprecated some time ago. This is the updated code:
function dataURItoBlob(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var byteString = atob(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
// create a view into the buffer
var ia = new Uint8Array(ab);
// set the bytes of the buffer to the correct values
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ab], {type: mimeString});
return blob;
}
-
4The duplicated split seems a bit wasteful, given that this could be a very large string. – Jesse Crossen Nov 15 '16 at 18:50
-
2What is the role of the variable "ia" - its assigned a value but is never used in forming the blob. Why? – Blaze Mar 06 '17 at 06:45
-
Same question as @Blaze, why is the iteration over `ia` necessary? @devnull69 – Ward D.S. May 29 '17 at 08:43
-
1Blaze, Ward: ia is a *view* of the buffer. So when you set each byte in ia, it is writing into the buffer. Without the loop over ia the buffer will be completely empty. – Mat Jun 15 '17 at 19:47
-
1How do I find SO answer #6850276 ? – B T Jun 20 '17 at 01:27
-
This has some additional code for cases where the dataURI isn't encoding base64 data: https://gist.github.com/andipaetzold/d88f29caa0ddb3566759 – B T Jun 20 '17 at 01:34
-
1@BT : I guess https://stackoverflow.com/a/30407840/271577 is intended (note the redirected URL includes "#6850276"). – Brett Zamir Oct 16 '17 at 02:34
-
1I think this should be `var blob = new Blob([ia], ...);` – Alejandro Corredor Apr 05 '18 at 03:28
-
1FWIW, we can create the `ArrayBuffer` more directly: `Uint8Array.from(byteString, ch => ch.charCodeAt(0)).buffer`. – T.J. Crowder Apr 27 '20 at 09:50
-
`atob()` is marked incorrectly as deprecated in vscode. `window.atob()` is a workaround. – Krishna Oct 11 '21 at 12:10
-
NOTE: this code does not consider malformed URIs. You should first check whether the string starts with `data:` and just to be sure, try-catch it. Otherwise you'll crash your app – TeemuK Nov 23 '22 at 13:40
Like @Adria method but with Fetch api and just smaller [caniuse?]
Don't have to think about mimetype since blob response type just works out of the box
Warning: Can violate the Content Security Policy (CSP)
...if you use that stuff
var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
fetch(url)
.then(res => res.blob())
.then(blob => console.log(blob))
Don't think you could do it any smaller then this without using lib's

- 34,080
- 13
- 108
- 131
-
1Very elegant. Unfortunately edge 13 and safari doesn't support "fetch". – alex_1948511 Jul 04 '16 at 14:07
-
2
-
34Async version: `const blob = await (await fetch(url)).blob();` – Christian d'Heureuse Mar 29 '18 at 23:09
-
Works great, but the file doesn't have an extension when read from server. Any thoughts? – pauljeba Feb 26 '20 at 04:51
-
2The bigger problem of this `fetch` is it force to having a async API. – Dennis C May 21 '20 at 05:31
In modern browsers one can use the one liner suggested by Christian d'Heureuse in a comment:
const blob = await (await fetch(dataURI)).blob();
-
2One caveat with this approach is that this could violate your content security policy (CSP), if your application has any. – standielpls Jul 16 '21 at 16:29
-
Adding to what @standielpls commented, you'll have to add `connect-src data:` to your Content-Security-Policy – Danylo Fedorov Jun 23 '22 at 14:05
dataURItoBlob : function(dataURI, dataTYPE) {
var binary = atob(dataURI.split(',')[1]), array = [];
for(var i = 0; i < binary.length; i++) array.push(binary.charCodeAt(i));
return new Blob([new Uint8Array(array)], {type: dataTYPE});
}
input dataURI is Data URL and dataTYPE is the file type and then output blob object

- 487
- 7
- 18
-
1The `dataTYPE` is embedded in `dataURI` and hence should be parsed as in the first answer. – Zephyr was a Friend of Mine Aug 25 '16 at 19:07
-
dataURL2Blob has come from my plugin for image process, you can check out this link. I just copy my own code. https://github.com/xenophon566/html5.upload/blob/master/js/imageUtility.js – Shawn Wu Jun 01 '18 at 11:03
XHR based method.
function dataURLtoBlob( dataUrl, callback )
{
var req = new XMLHttpRequest;
req.open( 'GET', dataUrl );
req.responseType = 'arraybuffer'; // Can't use blob directly because of https://crbug.com/412752
req.onload = function fileLoaded(e)
{
// If you require the blob to have correct mime type
var mime = this.getResponseHeader('content-type');
callback( new Blob([this.response], {type:mime}) );
};
req.send();
}
dataURLtoBlob( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', function( blob )
{
console.log( blob );
});

- 8,651
- 4
- 37
- 30
-
-
Will not work in Safari - it will throw cross-origin error if page is loaded from HTTPS. – Martin Ždila Aug 25 '16 at 10:19
-
try:
function dataURItoBlob(dataURI) {
if(typeof dataURI !== 'string'){
throw new Error('Invalid argument: dataURI must be a string');
}
dataURI = dataURI.split(',');
var type = dataURI[0].split(':')[1].split(';')[0],
byteString = atob(dataURI[1]),
byteStringLength = byteString.length,
arrayBuffer = new ArrayBuffer(byteStringLength),
intArray = new Uint8Array(arrayBuffer);
for (var i = 0; i < byteStringLength; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {
type: type
});
}

- 28,732
- 11
- 78
- 85
Since none of these answers support base64 and non-base64 dataURLs, here's one that does based on vuamitom's deleted answer:
// from https://stackoverflow.com/questions/37135417/download-canvas-as-png-in-fabric-js-giving-network-error/
var dataURLtoBlob = exports.dataURLtoBlob = function(dataurl) {
var parts = dataurl.split(','), mime = parts[0].match(/:(.*?);/)[1]
if(parts[0].indexOf('base64') !== -1) {
var bstr = atob(parts[1]), n = bstr.length, u8arr = new Uint8Array(n)
while(n--){
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], {type:mime})
} else {
var raw = decodeURIComponent(parts[1])
return new Blob([raw], {type: mime})
}
}
Note: I'm not sure if there are other dataURL mime types that might have to be handled differently. But please let me know if you find out! Its possible that dataURLs can simply have any format they want, and in that case it'd be up to you to find the right code for your particular use case.

- 57,525
- 34
- 189
- 207
Create a blob using XHR API:
function dataURLtoBlob( dataUrl, callback )
{
var req = new XMLHttpRequest;
req.open( 'GET', dataUrl );
req.responseType = 'blob';
req.onload = function fileLoaded(e)
{
callback(this.response);
};
req.send();
}
var dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
dataURLtoBlob(dataURI , function( blob )
{
console.log( blob );
});
If you need something that works server-side on Google Apps Script, try:
function dataURItoBlob(dataURI) {
// convert base64 to Byte[]
// doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
var data = Utilities.base64Decode(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]
var blob = Utilities.newBlob(data);
blob.setContentType(mimeString);
return blob;
}

- 9,337
- 4
- 33
- 32
use
FileReader.readAsArrayBuffer(Blob|File)
rather than
FileReader.readAsDataURL(Blob|File)

- 6,291
- 3
- 26
- 22
-
2I have to store it as a DataURL for an indefinite period in localStorage, so using the alternative `ArrayBuffer` path won't work. – Shane Holloway Aug 28 '12 at 23:25