Basically I am willing to upload files directly to S3 via browser i.e without any web server acting as a middle-ware or proxy like this.
So I am generating pre-signed URL using boto3 library like this:
def put_url(self, key):
url = self.client.generate_presigned_url(
ClientMethod="put_object",
Params={
"Bucket": "visweswaran",
"Key": key
}
)
return url
and this returns a pre-signed URL which is completely fine. I am using JQuery to make ajax PUT request to the S3 to upload my file.
let file_data = document.getElementById("file_data").files[0];
var form = new FormData();
form.append("", file_data, "test.txt");
var settings = {
"url": url,
"method": "PUT",
"timeout": 0,
"processData": false,
"mimeType": "multipart/form-data",
"contentType": "text/plain",
"beforeSend": function(xhr){xhr.setRequestHeader('Content-Disposition', 'attachment');},
"data": form
};
$.ajax(settings).done(function (response) {
location.reload();
});
The file gets uploaded to the S3 successfully via browser. But when I open the file I see strange meta data getting added to the top of the file like this,
-----------------------------33057860671031084693134041830 Content-Disposition: form-data; name="name"
test.txt -----------------------------33057860671031084693134041830 Content-Disposition: form-data; name="file"; filename="test.txt" Content-Type: text/plain
I have also tried a more formal solution like Pluploader (https://www.plupload.com/) and I am facing the same problem. I would like somebody to point me in the right direction to fix it. Ant help is much appreciated.
References:
- https://softwareontheroad.com/aws-s3-secure-direct-upload/
- How to upload to AWS S3 directly from browser using a pre-signed URL instead of credentials?
Working Solution
I have tested with a video and you don't need a form. Just send the data directly
let video = document.getElementById("video_file").files[0];
var settings = {
"url": url,
"method": "PUT",
"timeout": 0,
"processData": false,
"data": video
};
$.ajax(settings).done(function (response) {
location.reload();
});