预签名 AWS S3 PUT url 无法使用 jquery 从客户端上传
Presigned AWS S3 PUT url fails to upload from client using jquery
刚开始使用 node.js aws 客户端生成预签名 url 并将其发送到浏览器供用户上传文件,但我收到以下消息:
SignatureDoesNotMatch The request signature we calculated does not
match the signature you provided. Check your key and signing method.
我参考了很多链接,看起来很基础,但我似乎失败了
https://github.com/aws/aws-sdk-js/issues/251
Direct Browser Upload to S3 with Meteor, jQuery and the AWS SDK
https://forums.aws.amazon.com/thread.jspa?messageID=556839
要么,我完全傻了,要么sdk实在是太难用了
节点:
var putParams = {
Bucket: config.aws.s3UploadBucket,
Key: filename,
ACL: 'public-read',
Expires: 120,
Body: '',
ContentMD5: 'false'
};
s3.getSignedUrl('putObject', putParams, function (err, url) {
if (!!err) {
console.error(err);
res.json({error: ''});
return;
}
res.json({
'awsAccessKeyId': config.aws.accessKeyId,
's3bucket': config.aws.s3UploadBucket,
's3key': filename,
's3policy': s3policy.policy,
's3signature': s3policy.signature,
'url': url
});
});
客户:
var fd = new FormData();
fd.append('file', file);
return new RSVP.Promise(function(resolve, reject) {
$.ajax({
url: uploadObj.url,
data: fd,
processData: false,
contentType: false,
crossDomain: true,
type: 'PUT',
success: function(json, textStatus, jqXhr){
console.log(json);
resolve(json);
},
error: function(jqXhr, textStatus, errorThrown){
reject({ jqXhr: jqXhr, textStatus: textStatus, errorThrown: errorThrown});
}
});
});
更新:为了回应一些评论,我确实为存储桶添加了一个有效的 CORS。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我遇到了同样的问题,但我不记得到底是什么问题,但这个答案可能会对您有所帮助 upload-file-from-angularjs-directly-to-amazon-s3-using-signed-url。
服务器:
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY});
AWS.config.region = 'eu-west-1';
app.post('/s', function (req, res) {
var s3 = new AWS.S3();
var params = {Bucket: 'BUCKETNAME', Key: req.body.name, ContentType: req.body.type};
s3.getSignedUrl('putObject', params, function(err, url) {
if(err) console.log(err);
res.json({url: url});
});
});
客户:
$.ajax({
url: '/s',
type: 'POST',
data: {name: file.name, size: file.size, type:file.type},
}).success(function(res){
$.ajax({
url: res.url,
type: 'PUT',
data: file,
processData: false,
contentType: file.type,
}).success(function(res){
console.log('Done');
});
我也一直在和这个作斗争。这对我有用,我遇到了与您完全相同的错误。
在服务器端,我使用 AWS-SDK for nodejs
var params = {
Bucket: "bucketname",
Key: "filename",
ContentType: "multipart/form-data"
}
var url = s3.getSignedUrl('putObject', params, function(err, url) {
console.log(url);
}
客户端
$.ajax({
method: "PUT",
headers: {"Content-Type": "multipart/form-data"},
processData: false,
url: "http://AWSURL?AWSAccessKeyId..."
})
我觉得你的 cors 很合适,关键是要确保 Content-Type 的 headers 完全匹配
非常感谢 jeremy 和 kungfoo!我遇到了同样的问题,但在使用 Python 的 boto 库时增加了一些麻烦。如果您从 Python 生成 URL,最低工作配置似乎是:
Python
Boto3 有效但 Boto2 无效!
import boto3
conn = boto3.client('s3', ...)
url = conn.generate_presigned_url('put_object', {
'Bucket': my_bucket_name,
'Key': my_bucket_key,
'ContentType': 'my_content_type'
}, 300)
S3(CORS)
最低要求的规则似乎是:
<CORSRule>
<AllowedOrigin>*.mydomain.com</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
客户
使用 jQuery,并确保保持与以前相同的内容类型:
$.ajax({
type: "PUT",
headers: {"Content-Type": "my_content_type"},
url: url_from_server,
data: my_data_as_string,
processData: false,
contentType: false,
crossDomain: true,
cache: false
});
刚开始使用 node.js aws 客户端生成预签名 url 并将其发送到浏览器供用户上传文件,但我收到以下消息:
SignatureDoesNotMatch The request signature we calculated does not match the signature you provided. Check your key and signing method.
我参考了很多链接,看起来很基础,但我似乎失败了
https://github.com/aws/aws-sdk-js/issues/251
Direct Browser Upload to S3 with Meteor, jQuery and the AWS SDK
https://forums.aws.amazon.com/thread.jspa?messageID=556839
要么,我完全傻了,要么sdk实在是太难用了
节点:
var putParams = {
Bucket: config.aws.s3UploadBucket,
Key: filename,
ACL: 'public-read',
Expires: 120,
Body: '',
ContentMD5: 'false'
};
s3.getSignedUrl('putObject', putParams, function (err, url) {
if (!!err) {
console.error(err);
res.json({error: ''});
return;
}
res.json({
'awsAccessKeyId': config.aws.accessKeyId,
's3bucket': config.aws.s3UploadBucket,
's3key': filename,
's3policy': s3policy.policy,
's3signature': s3policy.signature,
'url': url
});
});
客户:
var fd = new FormData();
fd.append('file', file);
return new RSVP.Promise(function(resolve, reject) {
$.ajax({
url: uploadObj.url,
data: fd,
processData: false,
contentType: false,
crossDomain: true,
type: 'PUT',
success: function(json, textStatus, jqXhr){
console.log(json);
resolve(json);
},
error: function(jqXhr, textStatus, errorThrown){
reject({ jqXhr: jqXhr, textStatus: textStatus, errorThrown: errorThrown});
}
});
});
更新:为了回应一些评论,我确实为存储桶添加了一个有效的 CORS。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Authorization</AllowedHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我遇到了同样的问题,但我不记得到底是什么问题,但这个答案可能会对您有所帮助 upload-file-from-angularjs-directly-to-amazon-s3-using-signed-url。
服务器:
var AWS = require('aws-sdk');
AWS.config.update({accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY});
AWS.config.region = 'eu-west-1';
app.post('/s', function (req, res) {
var s3 = new AWS.S3();
var params = {Bucket: 'BUCKETNAME', Key: req.body.name, ContentType: req.body.type};
s3.getSignedUrl('putObject', params, function(err, url) {
if(err) console.log(err);
res.json({url: url});
});
});
客户:
$.ajax({
url: '/s',
type: 'POST',
data: {name: file.name, size: file.size, type:file.type},
}).success(function(res){
$.ajax({
url: res.url,
type: 'PUT',
data: file,
processData: false,
contentType: file.type,
}).success(function(res){
console.log('Done');
});
我也一直在和这个作斗争。这对我有用,我遇到了与您完全相同的错误。
在服务器端,我使用 AWS-SDK for nodejs
var params = { Bucket: "bucketname", Key: "filename", ContentType: "multipart/form-data" } var url = s3.getSignedUrl('putObject', params, function(err, url) { console.log(url); }
客户端
$.ajax({ method: "PUT", headers: {"Content-Type": "multipart/form-data"}, processData: false, url: "http://AWSURL?AWSAccessKeyId..." })
我觉得你的 cors 很合适,关键是要确保 Content-Type 的 headers 完全匹配
非常感谢 jeremy 和 kungfoo!我遇到了同样的问题,但在使用 Python 的 boto 库时增加了一些麻烦。如果您从 Python 生成 URL,最低工作配置似乎是:
Python
Boto3 有效但 Boto2 无效!
import boto3
conn = boto3.client('s3', ...)
url = conn.generate_presigned_url('put_object', {
'Bucket': my_bucket_name,
'Key': my_bucket_key,
'ContentType': 'my_content_type'
}, 300)
S3(CORS)
最低要求的规则似乎是:
<CORSRule>
<AllowedOrigin>*.mydomain.com</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
客户
使用 jQuery,并确保保持与以前相同的内容类型:
$.ajax({
type: "PUT",
headers: {"Content-Type": "my_content_type"},
url: url_from_server,
data: my_data_as_string,
processData: false,
contentType: false,
crossDomain: true,
cache: false
});