由于 CORS,使用 createPresignedPost 或 getPresignedUrl 将 formData 文件从客户端上传到 S3 失败
Uploading formData file from client to S3 using createPresignedPost or getPresignedUrl fails due to CORS
我正在使用 React 网络应用程序并尝试将文件上传到 AWS S3。
我已经在本地 (localhost:3000
) 和部署到生产环境时(Vercel 无服务器函数)尝试了一切。
我首先使用 fetch 检索预签名的 url 用于文件上传,效果很好:
module.exports = async (req, res) => {
let {fileName, fileType} = req.body;
const post = await s3.createPresignedPost({
Bucket: BUCKET_NAME,
Fields: {
key: fileName
},
ContentType: fileType,
Expires: 60
});
res.status(200).json(post);
然后,在第二次获取中:
await fetch(url, {method: 'POST', body: formData}
我得到:
fetch has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
我已在存储桶配置中正确设置权限 -> CORS json:
[
{
"AllowedHeaders": [
"*",
"Content-*"
],
"AllowedMethods": [
"HEAD",
"GET",
"PUT",
"POST",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"*"
]
}
]
我还在代码中验证了存储桶名称。
我试过:
getPresignedUrl
& createPresignedPost
生成 url
PUT
和 POST
请求
- 在获取请求中设置 headers (
Content-Type
, x-amz-acl
)
- 使用不同的 CORS json,允许所有来源,公开不同的 headers,允许所有方法(包括
HEAD
,允许不同的 headers(如 "Content-*"
)
- 为不同的用户配置不同的权限(特别是我需要的,所有 S3 权限等)
- Settings bucket policy
- 清除 Chrome 的缓存(使用 Hard Reload)或在每次尝试
之前通过
我已经尝试了所有方法并浏览了数十篇文章 (1, 2) 并浏览了此处的问题 - 但仍然无法正常工作。不在本地,也不在生产中。
确保文件名与 Key
完全匹配
const bucketParms = {
Bucket: "sample-temp-bucket",
Key: "HeadShot.jpg",
Expires: 3600,
};
s3.getSignedUrl("putObject", bucketParms, (error, url) => {
if (error) console.log("error", error);
if (url) console.log("url", url);
});
在这里我们可以测试从
生成的url
然后我们可以进行 http PUT
调用。
this.http
.put(
"https://sample-temp-bucket.s3.amazonaws.com/HeadShot.jpg?X-Amz-Algorithm=AWS4-HMAC....",
formData
)
.subscribe((response) => {
console.log("response received is ", response);
});
和 CORS,ExposeHeaders
的通配符不接受(至少从控制台),它只使用空数组 "ExposeHeaders": []
经过无数小时的深入研究,我发现了问题所在。
CORS 错误的原因是我没有在初始 AWS.config.update
配置设置中包含 region
。
添加 region
密钥后,CORS 错误已解决:
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: 'XXXXX',
secretAccessKey: 'XXXXXX',
region: 'us-west-2', // Must be the same as your bucket
});
const s3Client = new AWS.S3();
未配置bucket region返回的错误是CORS,真是令人困惑和误导。
我正在使用 React 网络应用程序并尝试将文件上传到 AWS S3。
我已经在本地 (localhost:3000
) 和部署到生产环境时(Vercel 无服务器函数)尝试了一切。
我首先使用 fetch 检索预签名的 url 用于文件上传,效果很好:
module.exports = async (req, res) => {
let {fileName, fileType} = req.body;
const post = await s3.createPresignedPost({
Bucket: BUCKET_NAME,
Fields: {
key: fileName
},
ContentType: fileType,
Expires: 60
});
res.status(200).json(post);
然后,在第二次获取中:
await fetch(url, {method: 'POST', body: formData}
我得到:
fetch has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
我已在存储桶配置中正确设置权限 -> CORS json:
[
{
"AllowedHeaders": [
"*",
"Content-*"
],
"AllowedMethods": [
"HEAD",
"GET",
"PUT",
"POST",
"DELETE"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [
"*"
]
}
]
我还在代码中验证了存储桶名称。
我试过:
getPresignedUrl
&createPresignedPost
生成 urlPUT
和POST
请求- 在获取请求中设置 headers (
Content-Type
,x-amz-acl
) - 使用不同的 CORS json,允许所有来源,公开不同的 headers,允许所有方法(包括
HEAD
,允许不同的 headers(如"Content-*"
) - 为不同的用户配置不同的权限(特别是我需要的,所有 S3 权限等)
- Settings bucket policy
- 清除 Chrome 的缓存(使用 Hard Reload)或在每次尝试 之前通过
我已经尝试了所有方法并浏览了数十篇文章 (1, 2) 并浏览了此处的问题 - 但仍然无法正常工作。不在本地,也不在生产中。
确保文件名与 Key
const bucketParms = {
Bucket: "sample-temp-bucket",
Key: "HeadShot.jpg",
Expires: 3600,
};
s3.getSignedUrl("putObject", bucketParms, (error, url) => {
if (error) console.log("error", error);
if (url) console.log("url", url);
});
在这里我们可以测试从
然后我们可以进行 http PUT
调用。
this.http
.put(
"https://sample-temp-bucket.s3.amazonaws.com/HeadShot.jpg?X-Amz-Algorithm=AWS4-HMAC....",
formData
)
.subscribe((response) => {
console.log("response received is ", response);
});
和 CORS,ExposeHeaders
的通配符不接受(至少从控制台),它只使用空数组 "ExposeHeaders": []
经过无数小时的深入研究,我发现了问题所在。
CORS 错误的原因是我没有在初始 AWS.config.update
配置设置中包含 region
。
添加 region
密钥后,CORS 错误已解决:
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId: 'XXXXX',
secretAccessKey: 'XXXXXX',
region: 'us-west-2', // Must be the same as your bucket
});
const s3Client = new AWS.S3();
未配置bucket region返回的错误是CORS,真是令人困惑和误导。