Lambda服务端与React客户端POST请求出现CORS错误求助
我的CORS配置在发起GET请求时正常,但改为POST请求时出现以下错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://... (Reason: CORS preflight response did not succeed). Status code: 422.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://... (Reason: CORS request did not succeed). Status code: (null).
客户端(React fetch)和服务端(Node.js Lambda)的配置如下:
// React(fetch): const fetch_params = { method: 'POST', mode: "cors", // GET请求时不需要这个参数也能正常工作 body: JSON.stringify(fetch_body), headers: new Headers({ "Content-Type": 'application/json' }) }
// Lambda(Node): response_headers: { "Access-Control-Allow-Headers" : "Content-Type", "Access-Control-Allow-Origin": event.headers.origin, // 返回请求对应的源 "Access-Control-Allow-Methods": "OPTIONS,POST,GET" }
本地运行React应用时GET请求正常,但将应用部署到HTTPS的AWS Amplify后,POST请求依然报错。目前Amplify与Lambda处于不同VPC,无法部署到同一VPC中。
问题分析与解决方案
1. 必须显式处理OPTIONS预请求
当POST请求携带Content-Type: application/json时,浏览器会自动发送OPTIONS预请求来验证跨域权限。你的Lambda当前未处理这类请求,导致预请求返回422错误,直接阻断了后续的POST请求。
修复代码示例:
在Lambda处理逻辑最前端添加OPTIONS请求的响应逻辑:
exports.handler = async (event) => { // 优先处理OPTIONS预请求 if (event.httpMethod === 'OPTIONS') { return { statusCode: 200, headers: { "Access-Control-Allow-Headers": "Content-Type", "Access-Control-Allow-Origin": event.headers.origin, "Access-Control-Allow-Methods": "OPTIONS,POST,GET" }, body: JSON.stringify('Preflight OK') }; } // 原有POST/GET请求的业务逻辑 // ... 你的业务代码 };
2. 检查VPC网络配置
虽然GET请求正常,但POST预请求可能被VPC的安全规则拦截:
- 确认Lambda所在VPC的安全组允许Amplify的公网IP段发起443端口的HTTPS请求
- 检查VPC的网络ACL,确保入站和出站的443端口流量都被允许
- 如果Lambda部署在私有子网,需配置NAT网关确保其能响应公网的Amplify请求
3. 限制动态Origin的范围
使用event.headers.origin动态返回Origin时,建议添加白名单验证,避免非法源的请求:
const allowedOrigins = ['https://your-amplify-domain.com', 'http://localhost:3000']; const requestOrigin = event.headers.origin; const validOrigin = allowedOrigins.includes(requestOrigin) ? requestOrigin : allowedOrigins[0]; // 在响应头中使用验证后的Origin headers: { "Access-Control-Allow-Origin": validOrigin, // ... 其他CORS头 }
内容的提问来源于stack exchange,提问作者Dalhousie

