AWS API Gateway预检请求触发CORS错误,求助排查解决方法
问题背景
本地和Postman中运行正常的小型应用,部署到AWS后架构为:S3托管React应用+CloudFront分发,Serverless Node.js(Lambda)+API Gateway。GET请求CORS问题已解决,但POST请求在浏览器中触发CORS错误,Postman调用正常。浏览器报错:
Access to fetch at 'apirul' from origin 'cloudfronturl' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
当前serverless.yml配置:
functions: api: handler: server.handler events: - httpApi: path: /rsb/vote/{voteId} method: GET - httpApi: path: /rsb/vote method: POST cors: origin: '*' headers: - Content-Type - X-Amz-Date - Accept - Authorization - X-Api-Key - X-Amz-Security-Token - X-Amz-User-Agent allowCredentials: false
需要检查的配置项
1. 确保OPTIONS预检请求被正确处理
浏览器发送POST请求前会先触发OPTIONS预检,当前配置仅给POST路由添加了CORS规则,需明确处理OPTIONS请求:
- 若使用
serverless-http包装Express应用,需在Express中全局配置CORS中间件,覆盖所有请求类型:const cors = require('cors'); app.use(cors({ origin: '*', allowedHeaders: ['Content-Type', 'X-Amz-Date', 'Accept', 'Authorization', 'X-Api-Key', 'X-Amz-Security-Token', 'X-Amz-User-Agent'], credentials: false, methods: ['GET', 'POST', 'OPTIONS'] })); - 若手动处理Lambda请求,需在handler中单独响应OPTIONS请求:
exports.handler = async (event) => { if (event.httpMethod === 'OPTIONS') { return { statusCode: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Content-Type,X-Amz-Date,Accept,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent', 'Access-Control-Allow-Methods': 'GET,POST,OPTIONS' }, body: '' }; } // 处理POST/GET请求的逻辑 };
2. 配置HTTP API全局CORS规则
避免仅在单个路由配置CORS,建议在API Gateway控制台为HTTP API设置全局CORS:
- 进入目标HTTP API的「CORS」配置页面
- 设置允许的源(Origin)为
*或你的CloudFront域名 - 允许的方法包含
GET, POST, OPTIONS - 允许的Headers与serverless.yml中配置保持一致
- 全局配置会自动生成OPTIONS路由并应用CORS规则,无需手动添加
3. 检查API Gateway与Lambda的关联路由
确认API Gateway中的/rsb/vote POST路由和对应的{proxy+}路由都正确关联到Lambda函数,且路由配置未覆盖CORS规则。
4. 检查CloudFront(若API前有CloudFront分发)
如果API Gateway前端配置了CloudFront,需确保:
- 在CloudFront行为的「缓存策略」中,允许缓存
Access-Control-Allow-Origin等CORS响应头 - 在「源请求策略」中,转发
Origin请求头到API Gateway,否则API无法判断请求来源,可能返回错误的CORS头 - 若有缓存,需手动刷新CloudFront缓存,确保新配置生效
5. 验证部署生效
修改配置后,重新部署Serverless服务(执行serverless deploy),并确认API Gateway和CloudFront的配置已更新。部分配置可能需要数分钟生效。
内容的提问来源于stack exchange,提问作者Matija

