簡體   English   中英

如何正確將對象上傳到AWS S3?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM