我有一个 lambda 来生成预签名的上传 URL。这是我用来获取 URL 的代码:
urlExpiresAt := time.Duration(10) * time.Second
s3Session := s3.New(awsSession)
request, _ := s3Session.PutObjectRequest(&s3.PutObjectInput{
Bucket: aws.String(awssettings.FileStorageBucketName),
Key: aws.String(fmt.Sprintf("%s/%s", *cognitoUser.Username, filename)),
ContentType: aws.String(uploadContentType),
})
uploadUrl, err := request.Presign(urlExpiresAt)
在我的前端,我检索该 URL 并立即尝试向它发送上传 POST 请求:
try {
const {
data: { fileUploadUrl },
} = await graphQlClient.query({
query: gql(getFileUploadUrlQuery),
variables: {
filename,
},
});
const formdata = new FormData();
formdata.append("file", file);
const ajaxRequest = new XMLHttpRequest();
ajaxRequest.upload.addEventListener("progress", progressHandler, false);
ajaxRequest.addEventListener("load", completeHandler, false);
ajaxRequest.addEventListener("error", errorHandler, false);
ajaxRequest.addEventListener("abort", abortHandler, false);
ajaxRequest.open("POST", fileUploadUrl);
ajaxRequest.send(formdata);
} catch (err) {
console.log(err);
}
出于测试目的,我将我的存储桶配置为可公开访问:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "UploadFiles",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "<bucketARN>/*"
}
]
}
用于测试目的的 CORS 配置如下:
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"POST"
],
"AllowedOrigins": [
"http://localhost:8080"
],
"ExposeHeaders": []
}
]
CORS 飞行前请求返回状态200,但是POST发送文件内容的请求被拒绝403并出现以下错误:
<Error>
<Code>AccessDenied</Code>
<Message>Request has expired</Message>
<X-Amz-Expires>5</X-Amz-Expires>
<Expires>2022-09-07T04:14:50Z</Expires>
<ServerTime>2022-09-13T06:40:18Z</ServerTime>
...
</Error>
阅读此错误,看起来 URL 在预签名之前已过期,这没有意义。
我在这里做错了什么?
侃侃无极
相关分类