Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a rails app on Heroku (cedar env). It has a page where I render the canvas data into an image using toDataURL() method. I'm trying to upload the returned base64 image data string directly to s3 using JavaScript (bypassing the server-side). The problem is that since this isn't a file, how do I upload the base64 encoded data directly to S3 and save it as a file there?

like image 981
Zain Zafar Avatar asked Oct 14 '12 15:10

Zain Zafar


People also ask

How do I load an image into Base64?

Images encoded with Base64 can be embedded in HTML by using the <img> tag. This can help to increase the page load time for smaller images by saving the browser from making additional HTTP requests.

How do I upload pictures to AWS S3?

Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that you want to upload your folders or files to. Choose Upload.

Does multipart form data use Base64?

It is worth noting though that in most (all?) cases, binary multipart/form-data data is encoded as base64.


2 Answers

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.

like image 140
jamcoupe Avatar answered Oct 15 '22 04:10

jamcoupe


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
like image 28
chevett Avatar answered Oct 15 '22 03:10

chevett