使用签名URL上传到AmazonS3可以使用curl,但不能使用javascript

使用签名URL上传到AmazonS3可以使用curl,但不能使用javascript,javascript,curl,amazon-web-services,file-upload,amazon-s3,Javascript,Curl,Amazon Web Services,File Upload,Amazon S3,我正在尝试使用PUT请求将文件上载到AmazonS3。我使用boto生成我的签名URL。如果我这样做 curl --upload-file test.jpg $SIGNED_URL 然后上传工作正常(因此签名的URL没有问题)。我还使用curl将referer设置为各种各样的东西,它仍然有效,所以我认为也没有CORS问题。我正在尝试使用javascript上传一个文件blob,如下所示: var xmlhttp = new XMLHttpRequest(); xmlhttp.open(

我正在尝试使用PUT请求将文件上载到AmazonS3。我使用boto生成我的签名URL。如果我这样做

curl --upload-file test.jpg $SIGNED_URL
然后上传工作正常(因此签名的URL没有问题)。我还使用curl将referer设置为各种各样的东西,它仍然有效,所以我认为也没有CORS问题。我正在尝试使用javascript上传一个文件blob,如下所示:

var xmlhttp = new XMLHttpRequest();    
xmlhttp.open("PUT", $SIGNED_URL);
xmlhttp.setRequestHeader('Content-Type', blob.type);
xmlhttp.send(blob);
这总是返回403禁止的错误。我发现在网上很难找到任何关于从javascript将数据放入S3的信息。我现在意识到发布表单数据更为常见,但有没有办法修改我正在做的工作以使其也能正常工作

编辑:我现在找到了错误主体:

> <Error><Code>SignatureDoesNotMatch</Code> <Message>The request
> signature we calculated does not match the signature you provided.
> Check your key and signing method.</Message>

因此,似乎签名是个问题。同样,当我将url与curl一起使用时(即使在javascript中失败之后),同样的url也可以使用。

问题在于curl没有发送的“内容头”。无论是否显式添加,Chrome都会发送此标头。要获得一个使用此标题的已签名url,您需要传递headers={'Content-Type':Type}以在boto中生成_url。

对于我来说,问题是在生成预签名url时我没有设置内容类型,因此在生成预签名url时添加了该选项

java.util.Date expiration = new java.util.Date();
        long msec = expiration.getTime();
        msec +=  60 * 60 * 1000; // 1 hour.
        expiration.setTime(msec);

        GeneratePresignedUrlRequest generatePresignedUrlRequest =
                new GeneratePresignedUrlRequest("bucket_name", "someRandomKey");
        generatePresignedUrlRequest.setMethod(HttpMethod.PUT); // Default.
        generatePresignedUrlRequest.setExpiration(expiration);
        generatePresignedUrlRequest.setContentType("application/octet-stream");

        URL s = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
        System.out.println("Secure PUT URL is "+s);
这是卷曲

curl -v -X PUT \
  'generated_secure_url' \ 
  -H 'Content-Type:application/octet-stream' \
  --data-binary '@swiggy-hackathon.jpg'

谢谢你发这个帖子。这个答案救了我几个小时的命:)