API Gateway代理S3时PUT请求的CORS问题求助
解决AWS API Gateway代理S3时PUT请求的CORS预检500错误
问题现象
- API Gateway代理S3桶,GET请求正常返回存储桶内容,PUT请求在浏览器中触发CORS错误,提示预检请求未通过(无HTTP OK状态)
- curl发送OPTIONS预检请求返回500 Internal Server Error,Postman直接发送PUT请求可成功
- S3桶已配置允许所有源、方法和头的CORS规则
解决方案
1. 手动配置API Gateway的OPTIONS方法(替代默认CORS自动生成)
默认的CORS自动配置无法正确处理S3代理场景的预检请求,需手动创建OPTIONS方法:
- 进入API Gateway控制台,找到
dev阶段下的目标资源(比如/liftoffbio-data/{proxy+}) - 创建新的
OPTIONS方法:- 集成类型选择Mock(无需转发到S3,直接返回CORS响应)
- 在集成响应中添加200状态码映射,设置以下响应头:
Access-Control-Allow-Origin: *(或指定http://localhost:8080提升安全性)Access-Control-Allow-Methods: GET,PUT,OPTIONSAccess-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
- 部署API到
dev阶段(必须部署才能让配置生效)
2. 检查PUT路由的集成配置
- 确认PUT方法的集成请求设置:
- HTTP方法为
PUT,集成目标路径正确(比如用{proxy+}变量映射到S3对象键) - 集成凭据使用的IAM角色拥有
s3:PutObject权限,且角色信任关系允许API Gateway服务调用
- HTTP方法为
- 验证集成响应是否配置了200/201状态码映射,确保实际PUT请求成功时返回正确状态
3. 验证S3桶权限和IAM角色
- 检查API Gateway使用的IAM角色权限策略,确保包含:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:PutObject", "s3:GetObject"], "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] } - 检查S3桶的桶策略,允许该IAM角色访问:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:role/YOUR_API_GATEWAY_ROLE" }, "Action": ["s3:PutObject", "s3:GetObject"], "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*" } ] }
4. 重新测试
完成配置并部署后,用curl重新发送OPTIONS请求:
curl -v https://XXX.execute-api.us-west-1.amazonaws.com/dev/liftoffbio-data/test.jpg \ -X OPTIONS \ -H "Access-Control-Request-Method: PUT" \ -H "Access-Control-Request-Headers: content-type" \ -H "Origin: http://localhost:8080"
若返回200状态码,再用浏览器的fetch测试PUT请求即可正常工作。
关键说明
Postman能成功是因为它不会强制发送OPTIONS预检请求,而浏览器会对跨域PUT请求自动触发预检,因此问题核心是API Gateway的OPTIONS请求处理失败,而非S3的CORS配置。
内容的提问来源于stack exchange,提问作者Marco Blanchette
相关产品推荐
相关产品推荐

