使用签名上传URL从浏览器上传到S3失败

时间:2017-03-20 12:17:27

标签: javascript file-upload browser amazon-s3

我试图直接从浏览器上传文件到S3。为此,我在我的服务器上生成了已签名的上传网址。

当我尝试使用

从浏览器上传文件到生成的网址时
var xhr = new XMLHttpRequest();
xhr.open('PUT', signedUrl);     
xhr.send(file);

我收到以下错误

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

我可以使用curl使用以下命令上传到签名的URL

curl -T <file> -X PUT '<signed-url>'

浏览器将我的请求作为多部分表单数据发送,这导致了问题。我该如何解决这个问题?

我使用以下代码生成签名的网址

var params = {
    Bucket: bucket, 
    Key: s3Key,
    ACL: "authenticated-read",
    Expires: 600
};

S3.getSignedUrl('putObject', params, (err, data) => {
    const returnData = {
        url: data
    };
    reply(returnData);
});

编辑: 为了清楚起见,我允许所有来源以桶CORS配置发送PUT请求。

1 个答案:

答案 0 :(得分:0)

好的,问题是浏览器在请求标头中发送了Content-Type,但是没有为内容类型生成签名的URL。 而不是这个

var params = {
    Bucket: bucket, 
    Key: s3Key,
    ACL: "authenticated-read",
    Expires: 600
};
S3.getSignedUrl('putObject', params, ...);

我做了这个

var params = {
    Bucket: bucket, 
    Key: s3Key,
    ACL: "authenticated-read",
    Expires: 600,
    ContentType: require('mime').lookup(filename)
};
S3.getSignedUrl('putObject', params, ...);

它有效!