如何重用 CORS 预检和资源请求之间的连接?

Posted

技术标签:

【中文标题】如何重用 CORS 预检和资源请求之间的连接?【英文标题】:How to reuse connections between CORS Preflight & Resource Request? 【发布时间】:2020-09-26 02:01:09 【问题描述】:

我将 AWS HTTP API 与 Lambda 代理集成一起使用。 API Gateway 不支持 Lambda 代理的 CORS 配置(不要在不知道的情况下质疑这个)。因此,我使用相同的 lambda 来提供 CORS Preflight 响应。

if(event.routeKey.startsWith('OPTIONS') 
  return 
    statusCode: 200,
    // CORS Headers
    ;


// Code for main methods like POST

(我使用API​​ Gateway Proxy Event的payload格式2.0版)

为了连接到 API,我使用 Angular。虽然,我在代码中只发出一个请求,但我的 API 收到了两个预期的请求。但是,我不确定 Angular 或浏览器本身是否发出了额外的请求。无论如何,我想完全控制 CORS 预检请求。如何做到这一点?

我想这样做的原因是因为 HTTP API 发送 coonection: keep-alive 标头,但资源请求没有使用相同的连接。结果是:如果 userA 在 CORS Preflight 请求中预热了 lambda(冷启动),则 userB 可以靠运气偷走努力,而 userA 可能需要预热新的 lambda,这会带来两个冷启动:一个用于 CORS Preflight 和另一个用于资源请求。

如何重用执行 CORS 预检的同一连接?

【问题讨论】:

您的询问不能在前端完成,CORS Preflight 请求是由浏览器本身发出的,而不是有角度的。您需要添加一些服务器逻辑来解决此问题。我想请您删除角度标签,因为您的问题与角度无关。 【参考方案1】:

你说:

API Gateway 不支持 Lambda 代理的 CORS 配置

那不是真的。我在没有启动 Lambda 函数的情况下为我的端点启用了 CORS。

以下 CloudFormation sn-p 在 API 网关中为我的 Resource 创建了 OPTIONS 方法,该方法将返回正确的 CORS 响应。

MyOptionsMethod:
  Type: "AWS::ApiGateway::Method"
  Properties:
    ApiKeyRequired: false
    AuthorizationType: None
    HttpMethod: OPTIONS
    Integration:
      Type: MOCK
      IntegrationResponses:
      - StatusCode: 200
        ResponseParameters:
          method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Api-Key,Access-Control-Allow-Origin'"
          method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'"
          method.response.header.Access-Control-Allow-Origin: "'*'"
        ResponseTemplates:
          application/json: ""
      PassthroughBehavior: NEVER
      RequestTemplates:
        application/json: '"statusCode": 200'
    MethodResponses:
    - StatusCode: 200
      ResponseModels:
        application/json: "Empty"
      ResponseParameters:
        method.response.header.Access-Control-Allow-Headers: true
        method.response.header.Access-Control-Allow-Methods: true
        method.response.header.Access-Control-Allow-Origin: true
    ResourceId: !Ref MyResource
    RestApiId: !Ref RestApi

如果您为 API 网关资源执行此操作,将启用 CORS,您无需仅为 CORS 响应执行 Lambda 函数。

【讨论】:

您添加了另一种方法,这是我已经在做的。 API Gateway 不支持 CORS 代理我的意思是 API Gateway 的 CORS 配置不适用于代理。 其次,即使您的 OPTIONS 方法也不起作用,因为 lambda 代理仍然需要返回一些 CORS 标头作为 CORS 规范的一部分。 第三,我说的是 HTTP API (v2) 而不是 Rest API (v1),所以我无法创建模拟集成来处理预检。所以,我必须使用 lambda 来处理预检。 第四,我问的是重用连接,而不是如何处理我正在成功做的CORS。

以上是关于如何重用 CORS 预检和资源请求之间的连接?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以手动预检多个 CORS 资源?

如何处理无效的 CORS 预检请求?

在 C# 和 Angular 之间启用预检 CORS

如何为 CORS 预检请求绕过 AWS API Gateway 代理资源上的 Cognito 授权方?

CORS 预检响应未成功

CORS预检请求详谈