I'm following Heroku's tutorial on direct uploads to Amazon S3.
After getting a signed request from AWS through the Node.js app, they use a "normal" XMLHttpRequest
to send the file.
This is their function:
function upload_file(file, signed_request, url){
var xhr = new XMLHttpRequest();
xhr.open("PUT", signed_request);
xhr.setRequestHeader('x-amz-acl', 'public-read');
xhr.onload = function() {
if (xhr.status === 200) {
document.getElementById("preview").src = url;
document.getElementById("avatar_url").value = url;
}
};
xhr.onerror = function() {
alert("Could not upload file.");
};
xhr.send(file);
}
Now, I'm working with Cordova and, since I don't get a File
object from the camera plugin, but only the file URI, I used Cordova's FileTransfer
to upload pictures to my Node.js app with multipart/form-data
and it worked fine.
However, I can't manage to make it work for Amazon S3.
Here's what I have:
$scope.uploadPhoto = function () {
$scope.getSignedRequest(function (signedRequest) {
if (!signedRequest)
return;
var options = new FileUploadOptions();
options.fileKey = 'file';
options.httpMethod = 'PUT';
options.mimeType = 'image/jpeg';
options.headers = {
'x-amz-acl': 'public-read'
};
options.chunkedMode = false;
var ft = new FileTransfer();
ft.upload($scope.photoURI, encodeURI(signedRequest.signed_request), function () {
// success
}, function () {
// error
}, options);
});
};
I've tried both chunkedMode = true
and chunkedMode = false
, but neither the success nor the error callback is called.
So, is there a way to upload a file to S3 with FileTransfer
?
Do I actually need the signed request or is it only necessary if I use XHR?
Any hint is appreciated.
I ended up with this function in Cordova:
The important bits are setting the
Content-Type
header, so thatmultipart/form-data
won't be used, andchunkedMode = false
to send the file with a single request.EDIT: Removed changes to the plugin code which were, in hindsight, useless (outdated plugin).
Not able to add comment: Strange. Works for me using $cordovaFileTransfer.upload. I don't have the 'x-amz-acl': 'public-read' header. Also I don't use encodeURI on the signed url. Have you been able to debug it? See any errors? I used chrome://inspect and port forwarding to connect to my app running on the phone, so I was able to debug the response from Amazon. Might be another reason why it's failing.