我正在尝试通过预先签名的网址将文件上传到S3。我已经通过使用curl
curl --request PUT --upload file {filename} "{url}"
把它推到那里A-OK。
但是,从javascript尝试时,我收到此消息:
我们计算的请求签名与您提供的签名不符。检查您的密钥和签名方法。
我已经采取了尽可能多的调试步骤 - 例如,确保预签名网址和我实际尝试上传的内容类型和内容长度匹配。
我发现了SO Thread并尝试了所有内容:
所以,我有点失落。任何人都可以确定导致S3拒绝此请求的原因是什么?
$(document).ready(function () {
$('[type=submit]').click(function (evt) {
evt.preventDefault();
console.log($('#id_attachment').get(0).files[0].size);
var reader = new FileReader();
reader.onloadend = function (evt) {
console.log(evt.target.result);
$.ajax({
url: 'https://bucketname.s3.amazonaws.com/simple.png?Signature=vYIEOmAay9v6zwB1cz78FhXv6Yo%3D&Expires=1416243285&AWSAccessKeyId=ACCESSKEY',
type: 'PUT',
contentType: "image/png",
data: evt.target.result,
success: function () {
console.log('Uploaded data successfully.');
}
});
};
reader.readAsBinaryString($('#id_attachment').get(0).files[0]);
});
});
答案 0 :(得分:2)
创建预签名网址时,您是指定图像/ png的内容类型,还是任何内容类型?
如果您不是,因为您在浏览器上传中包含Content-Type,则亚马逊可能会引用的签名不匹配是ajax PUT 具有Content-Type标题,但签名网址上的签名不会。
我最近遇到了这个问题,因为我使用.NET AWSSDK创建预签名的网址,而不是在生成网址时指定内容类型。
上传可以从一些普通的样本C#代码中正常工作,但在我的浏览器应用程序中失败,因为我使用的框架自动附加了Content-Type标头,导致不匹配。使用网络debbugger重新播放请求(我使用Fiddler),并从浏览器的请求中删除Content-Type标头,这是让我弄清楚是什么的原因导致我不匹配。