【问题标题】:AWS API Gateway CORS ok for OPTIONS, fail for POSTAWS API Gateway CORS 对 OPTIONS 正常,对 POST 失败
【发布时间】:2017-03-02 04:18:47
【问题描述】:

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

设置:

  • 通过 API 网关的 lambda 函数
  • 授权:无,需要 API KEY:false
  • 部署到阶段:测试

  • 1 个资源,1 个集成 lambda 的 POST 方法。

  • 直接调用 POST 端点,例如with curl 总是返回 200(有/没有有效负载、错误有效负载等) - 所以这与引用的问题不同。

我已使用“启用 CORS”选项 - 我已尝试在资源和 POST 请求(并随后部署 API)上应用此选项。

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

结果:在 Chrome 中从客户端代码调用端点,OPTIONS 通过但 POST 由于缺少 Access-Control-Allow-Origin 标头而失败。

在 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>

它返回:

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

和响应 json 正文 - 但没有 Access-anything 标头。

我还能检查什么?

【问题讨论】:

    标签: amazon-web-services cors aws-lambda aws-api-gateway


    【解决方案1】:

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

    我相信在将 API 网关触发器添加到新创建的 lambda 函数时,默认情况下会激活此功能。

    在 API Gateway - Resource - Method 视图中,“Integration Response”框显示为灰色,并且似乎无法(即使对于 Enable CORS 功能)在那里添加 Access-Control-Allow-Origin 标头,根据 @ Abhigna_Nagaraja 是必需的。

    解决方案: 如果使用“Lambda 代理集成”,请将 'Access-Control-Allow-Origin': '*' 标头添加到您的 lambda 函数中。

    更好的是:在同一视图 - 集成请求中,关闭“Lambda 代理集成”并再次启用 CORS(之后部署)。

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

    更新

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

    http status vs json status

    json status standards

    【讨论】:

    • 我相信新的“Lambda 代理集成”已经损坏,因为它只创建了一个新的 ANY 方法。它似乎没有与 CORS 完美集成,甚至与默认的 Lambda 触发器向导也没有完美集成。目前,我只能通过禁用“Lambda 代理集成”并手动创建 GET/POST 方法来解决此问题。
    • 根据我的经验,这部分是有效的。 ANY 方法是一个包罗万象的方法,在 LPI 的情况下,它将所有方法(POST、GET 等)定向到 lambda。但是,如果 lambda 有任何问题,则错误是非常具有误导性的。
    • “Lambda 代理集成”是一种控制 lambda 函数的状态代码和响应标头的方法。禁用代理集成将始终返回 200 响应,并且只允许您设置响应内容。当使用启用代理集成的 API GW 时,文档提到了在您的 lambda 中设置 CORS 标头。 (docs.aws.amazon.com/apigateway/latest/developerguide/…)
    【解决方案2】:

    “启用 CORS”选项是一个方便的工具,可以设置所有集成/方法响应标头映射。如果您单击“启用 CORS”,然后添加了新资源,它将没有所需的设置。您可以再次单击“启用 CORS”,也可以手动将其设置为

    • 将“Access-Control-Allow-Origin”方法响应标头添加到 POST 方法
    • 将“Access-Control-Allow-Origin”集成响应头映射添加到 POST 方法

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

    【讨论】:

    • 一切都按照您的建议完成。但是,在使用手动步骤确认时,我注意到一件事:方法响应看起来不错,但无法查看或编辑集成响应。该框显示“代理集成无法配置为转换响应”。我正在使用 Lambda 代理集成。这可能与我看到的问题有关吗?
    • 我能够通过将标头添加到 lambda 回调中的标头部分来获取标头。由于这看起来像是代码和配置的丑陋组合,我怀疑我们不应该在需要 CORS 时使用 Lambda 代理集成?
    • 您知道在 LPI 中将 CORS 标头添加到集成响应中是否已修复?
    【解决方案3】:

    如果您愿意使用 serverless-express 在您的 Lambda 中封装一个简单的 Express 应用程序,那么 Express cors package 可以让这个非常简单且高度可配置为 Lambda 代理。无需在 API Gateway 级别配置 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 })
    

    【讨论】:

      猜你喜欢
      • 2018-07-16
      • 2022-08-16
      • 2017-10-19
      • 2016-12-23
      • 1970-01-01
      • 2020-05-01
      • 2021-12-20
      • 2018-01-13
      • 2017-09-19
      相关资源
      最近更新 更多