'How to convert dataURL to file object in javascript?

I need to convert a dataURL to a File object in Javascript in order to send it over using AJAX. Is it possible? If yes, please tell me how.



Solution 1:[1]

The BlobBuilder is deprecated and should no longer be used. Use Blob instead of old BlobBuilder. The code is very clean and simple.

File object is inherit from Blob object. You can use both of them with FormData object.

function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}

use dataURLtoBlob() function to convert dataURL to blob and send ajax to server.

for example:

var dataurl = 'data:text/plain;base64,aGVsbG8gd29ybGQ=';
var blob = dataURLtoBlob(dataurl);
var fd = new FormData();
fd.append("file", blob, "hello.txt");
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server.php', true);
xhr.onload = function(){
    alert('upload complete');
};
xhr.send(fd);

Another way:

You can also use fetch to convert an url to a file object (file object has name/fileName property, this is different from blob object)

The code is very short and easy to use. (works in Chrome and Firefox)

//load src and convert to a File instance object
//work for any type of src, not only image src.
//return a promise that resolves with a File instance

function srcToFile(src, fileName, mimeType){
    return (fetch(src)
        .then(function(res){return res.arrayBuffer();})
        .then(function(buf){return new File([buf], fileName, {type:mimeType});})
    );
}

Usage example 1: Just convert to file object

srcToFile(
    'data:text/plain;base64,aGVsbG8gd29ybGQ=',
    'hello.txt',
    'text/plain'
)
.then(function(file){
    console.log(file);
})

Usage example 2: Convert to file object and upload to server

srcToFile(
    'data:text/plain;base64,aGVsbG8gd29ybGQ=',
    'hello.txt',
    'text/plain'
)
.then(function(file){
    console.log(file);
    var fd = new FormData();
    fd.append("file", file);
    return fetch('/server.php', {method:'POST', body:fd});
})
.then(function(res){
    return res.text();
})
.then(console.log)
.catch(console.error)
;

Solution 2:[2]

To create a blob from a dataURL:

const blob = await (await fetch(dataURL)).blob(); 

To create a file from a blob:

const file = new File([blob], 'fileName.jpg', {type:"image/jpeg", lastModified:new Date()});

Solution 3:[3]

If you really want to convert the dataURL into File object.

You need to convert the dataURL into Blob then convert the Blob into File. The function is from answer by Matthew. (https://stackoverflow.com/a/7261048/13647044)

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);
      var ia = new Uint8Array(ab);
      for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      return new Blob([ab], { type: mimeString });
    }

const blob = dataURItoBlob(url);
const resultFile = new File([blob], "file_name");

Other than that, you can have options on the File Object initialised. Reference to File() constructor.

const resultFile = new File([blob], "file_name",{type:file.type,lastModified:1597081051454});

The type should be [MIME][1] type(i.e. image/jpeg) and last modified value in my example is equivalent to Mon Aug 10 2020 19:37:31 GMT+0200 (Eastern European Standard Time)

Solution 4:[4]

In Latest browsers:

const dataURLtoBlob = (dataURL) => {
        fetch(dataURL)
            .then(res => res.blob())
            .then(blob => console.log(blob))
            .catch(err => console.log(err))
    }

Solution 5:[5]

After some research I arrived on this one:

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);
    var dw = new DataView(ab);
    for(var i = 0; i < byteString.length; i++) {
        dw.setUint8(i, byteString.charCodeAt(i));
    }
    // write the ArrayBuffer to a blob, and you're done
    return new Blob([ab], {type: mimeString});
}

module.exports = dataURItoBlob;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jan Derk
Solution 3 HeLin
Solution 4 Ubaid Badar
Solution 5 EpokK