![](/img/trans.png)
[英]How to upload an Image to Amazon AWS (S3) using Ajax and Jquery in Rails?
[英]How to properly upload an object to AWS S3?
經過三天的追逐這個問題。 是時候尋求幫助了。 我有一個簽名的URL,可以將文件上傳到Amazon S3。 我知道這是正確的,因為
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"
正確地成功。
但是我執行上載的.ajax代碼(如下)使內容在S3存儲桶中略有亂碼。
例如,如果我上傳一個.pdf文件,則可以從S3管理控制台正確加載該文件,但是如果它是.png或.jpeg等文件,則失敗...並且仔細查看該文件的長度(略有錯誤)。
瀏覽器中調用的核心是:
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');
這似乎幾乎可以正常工作,但是數據出現亂碼。 我嘗試將內容設置為file.type等,但無濟於事。 我在這里需要做一些編碼嗎? 如我所缺少的base64 ????
任何見識將不勝感激。
或者,如果有一種簡單的方法可以不使用.ajax來執行相同的操作,那將是很好的。
根據上面“ tedder42”提出的問題以及更多的實驗,我意識到發送FormData是問題。 因此,我將代碼更改為僅使用FileReader()並傳遞原始數據。 這很完美。 這是代碼:
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');
};
這要簡單得多,並且一切都可以完美運行。 然后,當稍后使用簽名的URL下載數據時,我只需輸入
ResponseContentDisposition: "attachment; filename="+fileData.name
作為s3.getSignedUrl('getObject',params)調用中的參數之一。
我在預先簽名的網址中輸入AND來檢索文件
ResponseContentDisposition: "attachment; filename="+fileData.name, 'ResponseContentType': fileData.type
這樣可以確保瀏覽器期望收到的內容。
因為在使用預簽名的url時上傳對象時無法設置內容類型,所以我還在服務器端添加了代碼,以在上傳完成后更改對象的內容類型。 這是代碼的核心:
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);
});
最終要正確做這是一個痛苦,我希望這將對其他人有所幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.