React使用react-aws-s3上传CSV至S3报400错误排查
React 上传文件到S3返回400 cors类型错误修复方案
首先明确:Fetch返回的type: "cors"不代表你CORS配置没开,只要跨域请求拿到的响应没带合法CORS头——包括S3拒绝请求返回错误页、根本没走到CORS校验逻辑的场景,都会标记成这个类型,你现在的问题是三个配置硬伤导致的:
1. 存储桶策略完全不满足上传要求,且格式错误
- 你当前配置的策略仅开放了
s3:List*、s3:Get*读权限,根本没加s3:PutObject上传权限,所有写请求直接会被S3拒绝。 - 策略里的资源ARN格式写错了:
arn:aws:s3::: my bucket name桶名前面多了空格,ARN匹配规则严格,这个写法等于策略完全没绑定到你的存储桶。
修正后的策略参考:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicUploadRead", "Effect": "Allow", "Principal": "*", "Action": [ "s3:ListBucket", "s3:GetObject", "s3:PutObject" ], "Resource": [ "arn:aws:s3:::替换为你的桶名(不要加多余空格)", "arn:aws:s3:::替换为你的桶名/*" ] } ] }
额外高危提醒:不要在前端代码里硬编码IAM访问密钥,哪怕存到前端环境变量也不行——React打包时会把这些变量直接注入静态JS文件,任何用户打开浏览器控制台都能拿到密钥,攻击者可以直接删光你桶内文件、盗刷你的云服务账单。正确做法是通过后端生成临时预签名URL给前端上传,全程不暴露长期密钥。
2. react-aws-s3 配置不全导致签名/请求路径错误
这个库本身有不少版本兼容坑,默认自动拼接S3端点的逻辑经常出错,缺少必填配置时会直接把请求发到错误的地址,S3返回的错误响应不会带CORS头,就会触发你看到的错误。
修正后的配置参考:
const config = { bucketName: S3_BUCKET, region: REGION, accessKeyId: ACCESS_KEY, secretAccessKey: SECRET_ACCESS_KEY, dirName: "uploads", // 可自定义,指定上传到桶内的目录,不填时部分版本会传空路径导致请求错误 s3Url: `https://${S3_BUCKET}.s3.${REGION}.amazonaws.com` // 手动指定正确的S3端点,避免库拼接错误 }; const ReactS3Client = new S3(config); // 额外校验传入的datasheet必须是原生File/Blob对象,自带name、type、size字段,否则库生成的请求头不符合S3要求 ReactS3Client.uploadFile(datasheet, datasheet.name) .then((data) => console.log(data.location)) .catch((err) => console.error(err));
3. 其他必查配置项
- 检查S3存储桶的「阻止公共访问」设置,确认最后两项“阻止通过公共桶策略授予的访问”处于关闭状态,否则你写的公开策略不会生效。
- 确认CORS配置编辑后已经点击保存,很多人改完没保存导致配置不生效,可以在ExposeHeaders里补加
Content-Length避免下载文件时出现跨域问题。 - 如果你开了桶的默认服务端加密,确认上传请求携带的加密参数和桶配置匹配,不过这类问题一般返回403而非400。
内容的提问来源于stack exchange,提问作者yankeedoodle
相关产品推荐
相关产品推荐

