AWS S3私有桶通过getSignedUrlPromise生成预签名链接上传文件报错如何解决?
S3预签名PUT URL上传失败解决方案
核心错误原因
- 生成预签名URL时未将
Content-Type纳入签名参数,前端上传时传入的Content-Type和签名计算时的参数不匹配,导致S3签名校验失败 - 前端上传时错误设置了
Content-Type: multipart/form-data,PUT方式直接上传单个文件不需要使用该格式
修复步骤
1. 修改预签名URL生成逻辑
生成签名时必须传入ContentType参数,值和后续上传文件的MIME类型保持一致:
export const generatePreSignedPutUrl = async (fileName, fileType) => { const params = ({ Bucket: bucketName, Key: fileName, Expires: URL_EXPIRATION_TIME, // 复用已定义的过期时间常量 ContentType: fileType // 新增,必须和上传时的Content-Type一致 }) const url = await s3.getSignedUrlPromise('putObject', params); return url; }
2. 修改前端上传代码
移除错误的Content-Type配置,直接传入文件对象即可,浏览器会自动设置正确的文件MIME类型:
const upload = async (e) => { e.preventDefault(); await JWT.checkJWT(); const requestObject = { fileName: frontPhoto.name, fileType: frontPhoto.type, token: JWT.getToken() }; const url = (await axiosReq.post(`${serverPath}/prepare_s3`, requestObject)).data.url; const response = await fetch(url, { method: "PUT", body: frontPhoto }); console.log(response); }
3. 兜底检查项
如果修改后仍然报错,请检查以下配置:
- IAM权限检查:确认你使用的AWS密钥对应的IAM用户,拥有该存储桶的
s3:PutObject权限,参考策略如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::atlasfitness-progress/*" } ] }
- 存储桶CORS配置检查:确认S3存储桶的CORS规则允许你前端域名发起PUT请求,参考配置如下:
[ { "AllowedHeaders": ["Content-Type"], "AllowedMethods": ["PUT", "GET"], "AllowedOrigins": ["替换为你的前端实际域名,例如https://example.com"], "ExposeHeaders": [] } ]
内容的提问来源于stack exchange,提问作者Gonsa02
相关产品推荐
相关产品推荐

