AWS API 网关 CORS 选项正常,POST 失败

AWS API Gateway CORS ok for OPTIONS, fail for POST

我查看了关于 SO 的其他相关问题,但这似乎有所不同。 事实上,我的问题与 this one 非常相似,只是我没有 400 状态问题。

设置:

我使用了 "Enable CORS" 选项 - 我尝试在资源和 POST 请求上应用此选项(然后部署 API)。

在API GW中,我可以看到Access-Control-Allow-Origin在POST方法-方法响应区域下的200 Response Headers中列出。

结果:从 Chrome 中的客户端代码调用端点,OPTIONS 通过但 POST 由于缺少 Access-Control-Allow-Origin header.

而失败

在 curl 中:OPTIONS 调用

curl -X OPTIONS -H "Access-Control-Request-Method: POST" \
     -H "Access-Control-Request-Headers: Content-Type" \
     -H "Origin: http://example.com" --verbose <endpoint>

响应是:

< HTTP/1.1 200 OK
< Content-Type: application/json
...
< Access-Control-Allow-Headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token
< Access-Control-Allow-Methods: POST,OPTIONS
< Access-Control-Allow-Origin: *
...

但 POST:

curl -X POST -d '{}' -H "Content-Type: application/json" \
     -H "Origin: http://example.com" --verbose <endpoint>

它returns:

< HTTP/1.1 200 OK
< Content-Type: application/json
...

和响应 json body - 但没有 Access-任何东西 header。

我还能检查什么?

'Enable CORS' 选项是一个方便的工具,可以设置所有 integration/method 响应 header 映射。如果您单击 'Enable CORS' 然后添加了一个新资源,它将没有所需的设置。您可以再次单击 'Enable CORS',也可以手动将其设置为

  • 将'Access-Control-Allow-Origin'方法响应Header添加到POST方法
  • 添加 'Access-Control-Allow-Origin' 集成响应 Header 映射到 POST 方法

此外,在使用 curl 测试更改之前,不要忘记部署 API。

问题是 API 网关使用选中的 "Lambda Proxy Integration" 选项调用了我的 lambda 函数。

我相信这是在向新创建的 lambda 函数添​​加 API 网关触发器时默认激活的。

在 API 网关 - 资源 - 方法视图中时,"Integration Response" 框显示为灰色,似乎无法(即使是启用 CORS 功能)添加 Access-Control-Allow-Origin header 那里,根据@Abhigna_Nagaraja 是必需的。

解决方法: 如果使用 "Lambda Proxy Integration",请将 'Access-Control-Allow-Origin': '*' header 添加到您的 lambda 函数中。

更好:在同一视图 - 集成请求中,关闭 "Lambda Proxy Integration" 并再次启用 CORS(之后部署)。

(然后,在回调中,您必须 return 只是有效负载 json 而不是 { statusCode, headers, body } object。)

更新:

如果您不确定是 return 在 http 状态代码中还是在 json 负载中请求响应状态信息,请阅读一些有用的文章:

http status vs json status

json status standards

如果您愿意使用 serverless-express to wrap a simple Express app in your Lambda, the Express cors package,那么这对于 Lambda 代理来说非常简单且高度可配置。无需在 API 网关级别配置 CORS。

index.js

const app = express();
app.use(cors());
// ...your backend implementation

lambda.js

const serverlessExpress = require('@vendia/serverless-express')
const app = require('./app')
exports.handler = serverlessExpress({ app })