I have got into almost every resource on the topic, but still need your help to make this work. I want to directly upload files to my S3 directly from the browser in my Meteor app. For this, I provide a signed url to the client just like in this simplified example:
Meteor.methods({
requestUpload: function(filename) {
var fut = new Future();
new Fiber(function() {
var params = {
Bucket: MY_BUCKET,
Key: new Date().getTime() + "_" + filename
};
var surl = s3.getSignedUrl('putObject', params, function(err, surl) {
if (!err) {
console.log("signed url: " + surl);
fut.return(data);
} else {
console.log("Error signing url " + err);
fut.return();
}
});
}).run();
return fut.wait();
}
}
The client then calls this method, obtains the signed url which looks like this
https://mybucket.s3-eu-west-1.amazonaws.com/1382890365957_myfile.png?AWSAccessKeyId=AKBLABLA&Expires=1382891265&Signature=BLABLA
and tries to upload the file with a POST request using jQuery like in this snippet:
Template.form.events({
'submit form': function(e, t) {
e.preventDefault();
var fileInput = t.find("input[type=file]");
for (var i = 0; i < fileInput.files.length; i++) {
var file = fileInput.files[i];
Meteor.call("requestUpload", file.name, function(err, surl) {
if (!err) {
console.log("signed url: " + surl);
var reader = new FileReader();
reader.onload = function(event) {
// Here I am trying to upload, it fails
$.post(surl, reader.result, function(data, status) {
console.log("status: " + status);
console.log("data: " + data);
});
};
reader.readAsDataURL(file);
} else {
console.log(err);
}
});
}
}
});
I want to use jQuery because I thing it's probably a good way to cover a lot of browsers and browser versions. I also checked my CORS configuration for this particular bucket, it looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
The credentials, that I configure my SDK with on the server are ensured to be alright, they have admin permissions and I am using them all the time for putting and getting objects in the S3 from the server. Also, if I sign a url for a GET call on a private file, the signed url is valid. I am probably doing something wrong with the post call.
Any help is very appreciated!