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