将 JPEG blob 发送到 S3:存储的文件是完整的多部分请求而不是 JPEG

Sending JPEG blob to S3: The stored file is the complete multipart request instead the JPEG

我的软件支持 "retouch" 图像,然后将生成的 canvas 作为 jpeg 图像从浏览器发送到 S3 存储桶。

首先,我使用 [https://github.com/blueimp/JavaScript-Canvas-to-Blob][1] 获取图像 Blob。

myCanvas.toBlob(function(blob){
  uploadFile("myImage.jpg", blob).then(function(){
    $log.log("upload finished");
  });
},"image/jpeg",90);

上传分两步进行:用我的应用服务器签署 S3 请求,然后上传到 S3 存储桶(使用 angular 文件上传 [https://github.com/danialfarid/angular-file-upload][1]

var uploadFile = function(fileName, blob){
  return signRequest(fileName).
    then(function(s3SignData){
      return $upload.upload({
        url: s3SignData.url,
        method: 'PUT',
        data: s3SignData.credentials,
        headers: {"x-amz-acl":s3SignData.credentials.acl},
        file: blob,
        fileName: fileName
      });

    });
  };

上传后,我可以在 S3 存储桶中找到文件,但令人惊讶的是,当我下载文件时 我没有 JPEG:我有多部分发送的请求

------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="policy"

eyJleHBpcmF0aW9uIjoiMjAxNS0wNC0wMVQxMjowMDowMC4wMDBaIiwiY29uZGl0aW9ucyI6W3siYnVja2V0IjoiZDRsIn0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCJmb2xkZXJzLzU1L2FhM2I3MmYxNjY3ZGM5OGEwOGI2YzVlNTk5Nzk5MTcyLzAwMDAwMF9MYW5kc2NhcGVfN19qcGcuanBnIl0seyJhY2wiOiJwdWJsaWMtcmVhZCJ9LFsiY29udGVudC1sZW5ndGgtcmFuZ2UiLDAsMjA5NzE1MjBdLFsiZXEiLCIkQ29udGVudC1UeXBlIiwiaW1hZ2UvanBlZyJdXX0=
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="signature"

RHmScYS9OIR/WkNoqBE9kZn6cJQ=
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="AWSAccessKeyId"

ZKSAJQFCLBSJEQJR6ZTQ
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="acl"

public-read
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="key"

aa3b/72f1667dc98a08b6c5e599799172/000000_Landscape_7_jpg.jpg
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="expires"

2015-04-01T12:00:00.000Z
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="content-type"

image/jpeg
------WebKitFormBoundaryBrzMD5YylSAtfLid
Content-Disposition: form-data; name="file"; filename="000000_Landscape_7_jpg.jpg"
Content-Type: image/jpeg

ÿØÿ........
Here all the file content 
.....
------WebKitFormBoundaryBrzMD5YylSAtfLid--

正如 michael-sqlbot 提到的,我必须使用 POST

另外,URL必须是bucketURL,而不是key:参数key是用来知道把文件放在哪里的水桶。

示例代码:

var uploadFile = function(fileName, blob){
  return signRequest(fileName).
    then(function(s3SignData){
      return $upload.upload({
        url: s3SignData.postURL,
        method: 'POST',
        data: s3SignData.postData,
        file: blob,
        fileName: fileName
      });

    });
  };

其中:

  • s3SignData.postURL === "mybucket.s3.amazonaws.com"
  • s3SignData.postData 包含所有 post 参数:"policy"、"signature"、"AWSAccessKeyId", "acl", "key", "content-type"