【发布时间】:2019-11-03 10:28:41
【问题描述】:
我遇到了一个问题,即 S3 在尝试将带有 PUT 请求的对象从客户端上传到签名 URL 时,偶尔会在 OPTIONS 请求飞行前返回 403。令人沮丧的是,90% 的时间它都能正常工作,而当它确实失败时,如果我重试相同的请求几次,它就会通过。
有没有人遇到过类似的事情,如果有,你是怎么解决的?
这似乎与this issue 相关,但并不完全相同,因为它们正在通过 CloudFront,而我将直接进入 S3。
在服务器端生成签名 URL
const params = {
Bucket: **my bucket**,
Key: 'test/my-test-file.csv',
Metadata: {
'created-by': req.user.id,
'job-id': job.id,
},
};
const url = s3.getSignedUrl('putObject', params);
Angular.JS 对签名 URL 的 HTTP 请求
return $http({
url: **signedUrlHere**,
method: 'PUT',
data: file,
headers: {
'Content-Type': '',
},
transformRequest: [],
});
存储桶 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>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
请求标头
Host: s3.amazonaws.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:67.0) Gecko/20100101 Firefox/67.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type
Referer: https://**.***.com/*/*/*
Origin: https://**.***.com
DNT: 1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
响应标头
HTTP/1.1 403 Forbidden
x-amz-request-id: *********
x-amz-id-2: *******
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Thu, 20 Jun 2019 02:54:39 GMT
Server: AmazonS3
【问题讨论】:
-
我认为这里的问题是为什么它向s3.amazonaws.com 发出选项请求,您可以尝试在签名网址中使用虚拟样式路径名。
-
看起来 JS SDK 中存在一个错误,使我无法在签名 URL 中使用虚拟样式路径,而无需付出太多额外的努力。希望他们能尽快解决这个问题。 github.com/aws/aws-sdk-js/issues/2653
-
“如果我重试同一个请求几次,它就会通过。” 这是否意味着完全同一个请求,并且使用完全相同的预签名 URL?还是每次都重签?
-
@Michael-sqlbot 我每次都重做签名。
-
这些签名的 URL 是否包含
AWSAccessKeyId(签名版本 2)或是否包含X-Amz-Credential(签名版本 4)?