[英]Uploading to S3 from browser using signed upload URL fails
I'm trying to upload a file to S3 directly from browser. 我正在尝试直接从浏览器将文件上传到S3。 For this, I'm generating a signed upload URL on my server.
为此,我正在服务器上生成一个签名的上传URL。
When I try to upload a file to the generated url from the browser using 当我尝试使用浏览器将文件上传到生成的url时
var xhr = new XMLHttpRequest();
xhr.open('PUT', signedUrl);
xhr.send(file);
I get the following error 我收到以下错误
<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>
I can upload to the signed URL using curl with the following command 我可以使用curl通过以下命令上传到签名的URL
curl -T <file> -X PUT '<signed-url>'
The browser is sending my request as multipart-form data which is causing the problem. 浏览器将我的请求作为多部分形式的数据发送,这导致了问题。 How do I fix the issue?
我该如何解决该问题?
I'm generating the signed URL using the following code 我正在使用以下代码生成签名的URL
var params = {
Bucket: bucket,
Key: s3Key,
ACL: "authenticated-read",
Expires: 600
};
S3.getSignedUrl('putObject', params, (err, data) => {
const returnData = {
url: data
};
reply(returnData);
});
Edit: Just to be clear, I have allowed all origins to send PUT requests in bucket CORS configuration. 编辑:为了清楚起见,我已允许所有来源在存储桶CORS配置中发送PUT请求。
Okay, the problem was that Content-Type was being sent by the browser in the request header but the signed url wasn't being generated for the content type. 好的,问题是浏览器在请求标头中发送了Content-Type,但没有为内容类型生成签名的url。 Instead of this
代替这个
var params = {
Bucket: bucket,
Key: s3Key,
ACL: "authenticated-read",
Expires: 600
};
S3.getSignedUrl('putObject', params, ...);
I did this 我做了这个
var params = {
Bucket: bucket,
Key: s3Key,
ACL: "authenticated-read",
Expires: 600,
ContentType: require('mime').lookup(filename)
};
S3.getSignedUrl('putObject', params, ...);
and it worked! 而且有效!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.