localhost:3000向AWS Lambda发POST请求遇CORS问题求助
问题场景
被CORS问题困扰超过两天,试过StackOverflow及AWS文档里的所有相关解决方案。场景是本地客户端(http://localhost:3000)向AWS Lambda发送POST请求,接口通过API Gateway暴露。
原有配置
API Gateway(CDK代码)
const apiGateway = new api_gw.LambdaRestApi(this, 'ingress-api', { handler: apiLambda, integrationOptions: { proxy: true, allowTestInvoke: true }, defaultCorsPreflightOptions: { allowOrigins: api_gw.Cors.ALL_ORIGINS, // 或指定自定义源列表 allowMethods: api_gw.Cors.ALL_METHODS, // 或指定自定义方法列表 allowHeaders: ['Content-Type', 'X-Amz-Date', 'Authorization', 'X-Api-Key'], // 自定义允许的请求头 }, });
Lambda响应代码
return { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "*", # 允许任意源请求 "Access-Control-Allow-Methods": "OPTIONS,GET,PUT,POST,DELETE,PATCH,HEAD", "Access-Control-Allow-Headers": "Content-Type" }, "body": json.dumps(response) }
测试现象
- 用
curl测试POST请求能得到正确响应,但浏览器始终报错:
Access to fetch at 'https://xxx.execute-api.us-east-1.amazonaws.com/prod/encode' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
- 用
curl测试OPTIONS方法,能看到正确的响应头:
access-control-allow-origin: *
access-control-allow-headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key
- 尝试将客户端POST请求的
Content-Type设为text/plain,问题依旧。
排查发现
在AWS控制台手动测试接口时,发现Lambda返回的headers被塞进了响应body里,而非作为真实的HTTP响应头返回——尽管已经配置了代理集成。
最终解决方案
把API Gateway从REST API换成HTTP API,在控制台配置CORS规则,同时修改Lambda代码,直接返回response对象(不用包裹在含statusCode、headers的结构中),问题最终解决。
内容的提问来源于stack exchange,提问作者Shrini

