Uploading image to Amazon S3 with javascript SDK


#1

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);
    q.resolve(imageURI);
  }, function(err) {
    q.reject(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!


#2

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.


#3

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";

app.use(express.logger("dev"));
app.use(express.methodOverride());
app.use(express.bodyParser());
app.use(app.router);

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.


#4

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 !


#5

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


#6

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