[英]How to properly upload an object to AWS S3?
After three days of chasing this problem. 经过三天的追逐这个问题。 It's time to ask for some help.
是时候寻求帮助了。 I have a signed url to upload a file to Amazon S3.
我有一个签名的URL,可以将文件上传到Amazon S3。 I know this is correct, since a
我知道这是正确的,因为
curl -v -T file.png --header "Content-Type:binary/octet-stream" "https://sample.s3.amazonaws.com/33d7e8f0-0fc5-11e5-9d95-2b3410860edd?AWSAccessKeyId=XXXXXXXX&Content-Type=binary%2Foctet-stream&Expires=1433984735&Signature=LUjj8iIAbCfNoskGhqLDhuEWVG4%3D"
succeeds correctely. 正确地成功。
But my .ajax code (below) which does the upload leaves the content garbled slightly in the S3 bucket. 但是我执行上载的.ajax代码(如下)使内容在S3存储桶中略有乱码。
For example if I upload a .pdf file, it loads properly from the S3 Management Console, but if it is a .png or .jpeg, etc. it fails... And looking closely the file has the wrong length (slightly). 例如,如果我上传一个.pdf文件,则可以从S3管理控制台正确加载该文件,但是如果它是.png或.jpeg等文件,则失败...并且仔细查看该文件的长度(略有错误)。
The heart of the call in the browser is: 浏览器中调用的核心是:
var formData = new FormData();
formData.append("upload", file);
$.ajax({ url: data.puturl,
type: 'PUT',
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', progressHandlingFunction,
false);
}
return myXhr;
},
success: completeHandler,
error: errorHandler,
data: formData,
cache: $.param(false),
contentType: "binary/octet-stream",
processData: $.param(false)
}, 'json');
This almost seems to work, but the data is garbled. 这似乎几乎可以正常工作,但是数据出现乱码。 I have tried setting the content to file.type, etc. to no avail.
我尝试将内容设置为file.type等,但无济于事。 Is there some encoding that I need to do here?
我在这里需要做一些编码吗? Such as base64 that I am missing????
如我所缺少的base64 ????
Any insight would be greatly appreciated. 任何见识将不胜感激。
OR if there is an easy way to not use .ajax to do the same thing, that would be great. 或者,如果有一种简单的方法可以不使用.ajax来执行相同的操作,那将是很好的。
From the question that 'tedder42' asked above, and some more experimentation, I realized that sending the FormData was the issue. 根据上面“ tedder42”提出的问题以及更多的实验,我意识到发送FormData是问题。 So I changed the code to just use a FileReader() and pass the raw data.
因此,我将代码更改为仅使用FileReader()并传递原始数据。 This works perfectly.
这很完美。 Here is the code:
这是代码:
var reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (e) {
var rawData = reader.result;
$.ajax({ url: data.puturl,
type: 'PUT',
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
}
return myXhr;
},
success: completeHandler,
error: errorHandler,
// Form data
data: rawData,
cache: $.param(false),
contentType: "binary/octet-stream",
processData: $.param(false)
}, 'json');
};
This is much more straightforward and everything works perfectly. 这要简单得多,并且一切都可以完美运行。 Then when the data is downloaded later using a signed url, I simply put
然后,当稍后使用签名的URL下载数据时,我只需输入
ResponseContentDisposition: "attachment; filename="+fileData.name
as one of the params in the s3.getSignedUrl('getObject', params) call. 作为s3.getSignedUrl('getObject',params)调用中的参数之一。
AND in the presigned url to retrieve the file, I put 我在预先签名的网址中输入AND来检索文件
ResponseContentDisposition: "attachment; filename="+fileData.name, 'ResponseContentType': fileData.type
which takes care of ensuring that the browser expects what it is receiving. 这样可以确保浏览器期望收到的内容。
Because you cannot set the content-type when uploading the object when using a pre-signed url, I also added code on the server side to change the object content-type after the upload has completed. 因为在使用预签名的url时上传对象时无法设置内容类型,所以我还在服务器端添加了代码,以在上传完成后更改对象的内容类型。 Here is the heart of the code:
这是代码的核心:
var params = {
Bucket: 'sample',
CopySource: 'sample/' + file.key,
Key: file.key,
MetadataDirective: 'REPLACE',
ContentType: type
};
s3.copyObject(params, function (err, data){
if (err) {
console.log(err);
validationError(res, 'unable to change content-type!');
}
res.sendStatus(200);
});
This was a pain to finally get right and I am hopeful that this will help others! 最终要正确做这是一个痛苦,我希望这将对其他人有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.