Stoive Stoive - 9 months ago 72
Javascript Question

Convert Data URI to File then append to FormData

I've been trying to re-implement an HTML5 image uploader like the one on the Mozilla Hacks site, but that works with WebKit browsers. Part of the task is to extract an image file from the

object and append it to a FormData object for upload.

The issue is that while
has the
function to return a representation of the image file, the FormData object only accepts File or Blob objects from the File API.

The Mozilla solution used the following Firefox-only function on

var file = canvas.mozGetAsFile("foo.png");

...which isn't available on WebKit browsers. The best solution I could think of is to find some way to convert a Data URI into a File object, which I thought might be part of the File API, but I can't for the life of me find something to do that.

Is it possible? If not, any alternatives?


Answer Source

After playing around with a few things, I managed to figure this out myself.

First of all, this will convert a dataURI to a Blob:

function dataURItoBlob(dataURI) {
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;
    if (dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for (var i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);

    return new Blob([ia], {type:mimeString});

From there, appending the data to a form such that it will be uploaded as a file is easy:

var dataURL = canvas.toDataURL('image/jpeg', 0.5);
var blob = dataURItoBlob(dataURL);
var fd = new FormData(document.forms[0]);
fd.append("canvasImage", blob);