AWS API Gateway 仅在使用 SAM 时支持 CORS for OPTIONS(没有 Lambda 代理集成)

Posted

技术标签:

【中文标题】AWS API Gateway 仅在使用 SAM 时支持 CORS for OPTIONS(没有 Lambda 代理集成)【英文标题】:AWS API Gateway supports CORS for OPTIONS only when using SAM (without Lambda proxy integration) 【发布时间】:2019-08-03 03:27:36 【问题描述】:

我正在使用 AWS Serverless 构建一个包含大约 15 个 Lambda 函数的小型站点。 我的 Cloudformation 堆栈完全使用 SAM 构建。

我没有使用 Lambda 代理集成。

SAM yaml 模板配置中的 Api 部分如下所示:

AppApi:
    Type: AWS::Serverless::Api
    Properties:
        Cors:
            AllowMethods: "'*'"
            AllowHeaders: "'Content-Type'" 
            AllowOrigin: "'*'"
    ...........More Stuff..........

当我部署这个 SAM yaml 模板时,我看到我的 ApiGateway 为所有方法创建了 OPTIONS 动词,当我使用 OPTIONS 动词发出请求时,我确实看到了 CORS 标头正确。

问题是其他动词(例如 POST)没有像 OPTIONS 请求那样将这些标头添加到它们的响应中,当我从浏览器运行我的 api 时,我的控制台中出现跨源策略错误。

所以我目前的解决方法是使用对特定状态代码的集成响应来添加 CORS 标头,但我不能也不想处理 15 种方法,我想支持所有响应状态代码(例如 4xx\5xx 等) .

我的问题:

    我在这里做错了什么还是SAM 错误? 如果这是一个错误,除了使用集成响应(或从我的代码)添加标头之外,还有其他解决方法吗? 有没有一种方法可以从 Api 网关“全局”添加标头?还是支持某种全球综合响应?

【问题讨论】:

【参考方案1】:

如果您将 Lambda 与代理集成一起使用,则需要在 HTTP 响应中指定 CORS 来源。

对于 Lambda 或 HTTP 代理集成,您仍然可以设置 API 网关中所需的 OPTIONS 响应标头。但是,您必须 依靠后端返回 Access-Control-Allow-Origin 标头 因为代理的集成响应被禁用 一体化。 https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

来自 Lambda 的所有响应都需要包含这些标头和状态代码,但您可以将其提取到共享库以减少代码重复。 API-G 处理的错误将自动添加标头。

你可能已经有了这个,但是 NodeJS 模式是这样的:

var response = 
    statusCode: 200,
    headers: 
        "Access-Control-Allow-Origin" : "*"
    ,
    body: JSON.stringify(
        someReturnData
    )
;
callback(null, response);

如果您真的不想这样做,那么您可以关闭 Lambda-Proxy 集成,但这意味着所有请求响应负载都需要在 API-G 而不是 Lambda 中处理。 IMO 这提供了更少的灵活性和实现相同结果所需的更多配置。

Here 是这两种方法的有趣比较。

【讨论】:

您好,感谢您的回答。我没有将 Lambda 与代理 int 一起使用。而且我不想在我的代码中添加 CORS 标头,因为我认为这是一种不好的做法,原因有很多(其中一个原因是您可以在输入代码之前从资源中获得响应,然后您将如何支持 CORS?) .现在我的替代方案是每个方法\动词的集成响应 - 也很糟糕,因为我不想涵盖所有错误代码(谁知道我会错过哪个错误代码)并且我不想向我的 YAML 模板发送垃圾邮件并处理每一个更改对于每个方法\动词。我正在寻找一种更好的方法来做到这一点.. 如果您没有使用 Lambda-Proxy,并且您已经在 API Gateway 中设置了 CORS 标头,那么您应该自动获取响应中的标头。作为测试,您是否尝试过在单个方法(控制台或 CLI)上手动启用 CORS,看看是否可行。 是的。我在模板中添加了 CORS 部分。部署模板后,每个返回有效响应的资源路径都有一个 OPTIONS 动词 create。当浏览器创建一个 xhr 请求时,它使用 OPTIONS 请求进行预检,该请求正确返回所有内容,然后继续执行“真实请求”(假设是 POST)。 POST 请求不返回 CORS 标头,然后浏览器简单地拒绝响应。我不知道这是一个错误还是我在这里遗漏的东西.. 抱歉,我不确定那里发生了什么。几年前我改用 Lambda-Proxy,CORS 不再是一个问题。在我参加过的 AWS Talks 和我参加的无服务器会议中强烈推荐 Lambda-Proxy。不过我必须承认,我不怎么使用 SAM,主要是无服务器框架。

以上是关于AWS API Gateway 仅在使用 SAM 时支持 CORS for OPTIONS(没有 Lambda 代理集成)的主要内容,如果未能解决你的问题,请参考以下文章

AWS SAM 模板 - 定义由 API Gateway 触发的 SQS 队列

AWS SAM/Cloudformation 配置 API Gateway 指向 lambda 函数版本

AWS Api Gateway 仅在 OPTIONS 调用时不响应 CORS 标头

具有 Cognito 用户池授权方的 AWS SAM API

AWS SAM :: AWS::Serverless::Api“'Auth' 属性的值无效”

是否可以使用 AWS API 为 Lambda 函数设置 AWS API Gateway 端点?