我使用Node获取S3的presignedRUL,以便将图像输入S3存储桶。
vertex shader
这成功检索了形式为...的预签名网址。
https://[my-bucket-name].s3.amazonaws.com/1233456?AWSAccessKeyId=[My-ID]&Expires=1517063526&Signature=95eA00KkJnJAgxdzNNafGJ6GRLc%3D (我是否必须包含过期标题?)
回到客户端(Web应用程序)我使用angular来生成HTTP请求。我使用了$ http和ngFileUpload,但也没有成功。这是我的ngFileUpload代码。
var aws = require('aws-sdk');
// Request presigned URL from S3
exports.S3presignedURL = function (req, res) {
var s3 = new aws.S3();
var params = {
Bucket: process.env.S3_BUCKET,
Key: '123456', //TODO: creat unique S3 key
//ACL:'public-read',
ContentType: req.body['Content-Type'], //'image/jpg'
};
s3.getSignedUrl('putObject', params, function(err, url) {
if(err) console.log(err);
res.json({url: url});
});
};
然而,似乎无论我如何格式化我的标题,我总是得到403错误。在它所说的错误的XML中,
Upload.upload({
url: responce.data.url, //S3 upload url including bucket name
method: 'PUT',
'Content-Type': file.type, //I have tried putting the ContentTyep header all over
headers: {
//'x-amz-acl':'public-read',
'Content-Type': file.type,
},
data: {
file: file,
headers:{'Content-Type': file.type,}
},
})
我不认为CORS是一个问题。最初我得到了一些CORS错误,但它们看起来不一样,我让他们对S3存储桶CORS设置进行了一些更改。我已尝试对presignedURL的请求和S3的PUT请求进行大量试验和错误设置,但我似乎无法找到正确的组合。
我注意到当我在console.log中出现403响应错误时,字段
SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.
这是说Content-Type头没有设置?当我能在任何地方设置标题时,怎么可能呢?无论如何,我的头撞到了墙上一点......
编辑:根据要求,我的当前CORS。 (我把所有内容全部丢掉,以摆脱我之前的CORS警告。只有在我的上传工作完成后,我才会将其削减到必需品。)
config.headers:{Content-Type: undefined, __setXHR_: ƒ, Accept: "application/json, text/plain, */*"}
答案 0 :(得分:2)
面对同样的问题。发现我用来创建预签名URL的内容类型与我发送给S3的对象的内容类型不匹配。我建议您在创建预签名的URL时添加Expiration标头(我也是这样做的),并在控制台中准确检查在对S3进行放置时要发送的内容类型。另外,数据只需要是文件,而不是您在其中创建的结构。
答案 1 :(得分:0)
我遇到了签名不匹配的 403 错误,我一生都无法弄清楚原因。阅读其他一些示例,其中一个说它必须在 us-east-1 中运行,因为其他区域不支持它。我在 us-east-2,切换和完全相同的代码工作。
尝试使用 us-east-1