Uploading image to Amazon S3 with javascript SDK

Hello everyone!

I am looking to upload an image to an Amazon bucket using the AWS Javascript for Browser SDK. The request is made successfully, but a broken image is uploaded. The image shows up on the client side though.

Accessing Camera and calling upload:

choosePhoto: function(){
  var q = $q.defer();

  var options = {
    quality : 40,
    destinationType : Camera.DestinationType.FILE_URI,
    sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
    allowEdit : true,
    encodingType: Camera.EncodingType.JPEG,
    targetWidth: 500,
    targetHeight: 500,
    popoverOptions: CameraPopoverOptions,
    saveToPhotoAlbum: false

  $cordovaCamera.getPicture(options).then(function(imageURI) {
    var fileName = "" + (new Date()).getTime() + ".jpg"; //
    uploadS3(imageURI, fileName);
  }, function(err) {

  return q.promise;

The image URI spits out something like file:///var/mobile/Containers/Data/Application/A9770E07-DE6C-4B49-9A4F-D836CD80C620/tmp/cdv_photo_006.jpg

and my upload function is very simple:

function uploadS3(image, name) {
  var bucket = new AWS.S3({params: {Bucket: 'my-bucket'}});
  var params = {Key: name, ContentType: 'image/jpeg', Body: image};
  bucket.upload(params, function(err, data){
    if(err){ alert(err); }

I have tried using window.resolveLocalFileSystemURL using fullPath but that failed for me as well.

Anybody worked through this problem before or have any alternative options for hosting images? I have been using the base64 and storing them in firebase, but it is causing too much bloat on the file.

Thank you!

1 Like

As far as I can see, you are not converting the image from base64 back to a binary image for storing on S3? I am guessing the file is just containing the base64 stream so the browser etc. cannot interpret it if it thinks it is a jpeg image?!?

Apart from that, I am really reluctant to use pure Javascript to manipulate S3 - too much of a chance for some nefarious person to unwrap your code and sniff out your access keys.

Far better to write a small uploader script in Ruby or PHP and host it on Heroku or somewhere and just use $http POST to post the image there. Let the server take care of the decoding and transfer to S3.

Thank you for your response!
I agree about having a signing server but I need to demo functionality very soon so I was just trying to create a temporary solution.

If you can help me conceptualize this, I would love it. I attempted to use a Node.js script to sign policy keys on demand

var express = require('express'),
http = require('http'),
path = require('path'),
crypto = require('crypto'),
app = express(),
bucket = "my-bucket",
awsKey = "my-key",
secret = "my-secret";


function sign(req, res, next) {

var fileName = req.body.fileName,
    expiration = new Date(new Date().getTime() + 1000 * 60 * 5).toISOString(); // expire in 5 minutes

var policy =
{ "expiration": expiration,
    "conditions": [
        {"bucket": bucket},
        {"key": fileName},
        {"acl": 'public-read'},
        ["starts-with", "$Content-Type", ""],
        ["content-length-range", 0, 524288000]

policyBase64 = new Buffer(JSON.stringify(policy), 'utf8').toString('base64');
signature = crypto.createHmac('sha1', secret).update(policyBase64).digest('base64');
res.json({bucket: bucket, awsKey: awsKey, policy: policyBase64, signature: signature});

app.post('/signing', sign);

app.listen(3000, function () {
console.log('Server listening on port 3000');

But I am a little confused about how this script is run without starting it from command line. I suppose I have to host this on heroku or some other hosting platform in order for it to run on its own? I am pretty noobish with Node/Backend in general.

Hey man,

I’m starting to try uploading media files from my app to S3. Could you point me in the right direction ? The Amazon docs are very confusing, so if you succeed I would really like a little help… Thank you !

Any info. available on this topic, heroku and s3. Thanks.

Thanks for the post. Im starting to upload videos to S3 as well but so far nothing happens. Any working tutorial out there?