How to upload base64 encoded image data to S3 using JavaScript only?

I have found a way to do this. After a lot of searching a looking at different tutorials.

You have to convert the Data URI to a blob and then upload that file to S3 using CORS, if you are working with multiple files I have separate XHR requests for each.

I found this function which turns your the Data URI into a blob which can then be uploaded to S3 directly using CORS (Convert Data URI to Blob )

function dataURItoBlob(dataURI) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: 'image/jpeg'});
}

Here is a great tutorial on uploading directly to S3, you will need to customise the code to allow for the blob instead of files.


If anyone cares: here is the coffescript version of the function given above!

  convertToBlob = (base64) ->
    binary = atob base64.split(',')[1]
    array = []
    for i in [0...binary.length]
      array.push binary.charCodeAt i
    new Blob [new Uint8Array array], {type: 'image/jpeg'}

Jamcoope's answer is very good, however the blob constructor is not supported by all browsers. Most notably android 4.1 and android 4.3. There are Blob polyfills, but xhr.send(...) will not work with the polyfill. The best bet is something like this:

var u = dataURI.split(',')[1],
    binary = atob(u),
    array = [];

for (var i = 0; i < binary.length; i++) {
    array.push(binary.charCodeAt(i));
}

var typedArray = Uint8Array(array);

// now typedArray.buffer can be passed to xhr.send