AWS Lambda部署Python Flask无服务API遇CORS预检请求失败求助
问题描述
我已完成项目环境搭建:使用RDS数据库、通过S3+CloudFront部署客户端、AWS Lambda作为Python后端运行Flask应用。
在Flask代码中配置了CORS:
CORS(app, resources={r"/*": {"origins": URL}}, supports_credentials=True)
同时在API Gateway中为GET、POST、PUT、DELETE方法配置了CORS,但客户端出现如下错误:
Access to fetch at [API SERVER URL] from origin [CLIENT URL] has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
请问我遗漏了什么配置?
排查与解决方向
API Gateway未正确配置OPTIONS方法
浏览器发起的预检请求(OPTIONS)是CORS验证的关键,你需要确保API Gateway对应资源下显式创建了OPTIONS方法,而非仅给GET/POST等业务方法配置CORS。- 检查OPTIONS方法的CORS配置:需包含
Access-Control-Allow-Origin、Access-Control-Allow-Methods、Access-Control-Allow-Headers等响应头,且与业务方法配置一致。 - 若使用Lambda代理集成,可将OPTIONS方法设为"MOCK"集成,直接返回200状态码和所需CORS头;或者在Lambda中显式处理OPTIONS请求,返回符合要求的响应。
- 检查OPTIONS方法的CORS配置:需包含
Flask CORS的
origins参数配置错误
确认URL变量是客户端的实际域名(如CloudFront分配的域名),注意协议(http/https)、域名格式要完全匹配,不要带多余路径或末尾斜杠。测试阶段可临时用"*"替代(生产环境不建议),验证是否为域名匹配问题。Lambda代理集成的响应头未正确传递
若API Gateway使用Lambda代理模式,Flask的CORS扩展可能无法自动将响应头传递到客户端,需手动构造包含CORS头的响应结构:return { 'statusCode': 200, 'headers': { 'Access-Control-Allow-Origin': '[CLIENT URL]', 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type' }, 'body': json.dumps(...) }CloudFront缓存或响应头拦截问题
检查CloudFront行为设置,确保允许Access-Control-Allow-Origin等CORS相关头传递到客户端。同时尝试清除浏览器缓存和CloudFront缓存,避免旧配置干扰测试结果。预检请求的响应状态异常
用curl或Postman直接发送OPTIONS请求到API地址,查看返回的状态码和响应头。如果返回403、404等非200状态,说明Lambda未处理OPTIONS请求(比如Flask路由未覆盖OPTIONS方法),或API Gateway的OPTIONS方法配置有误。
内容的提问来源于stack exchange,提问作者Noam Azoulay

