【问题标题】:AWS API Gateway OPTIONS requests returns 500 errorAWS API Gateway OPTIONS 请求返回 500 错误
【发布时间】:2017-12-13 06:24:07
【问题描述】:

我对 API Gateway 和 Lambda 非常陌生。我正在尝试将基于 Node.js Express 的 API 部署到 lambda。我正在使用来自 awslabs 的 aws-serverless-express example。因此,我的大部分 AWS 配置都是自动为我创建的。

我的 API 似乎通过 API 网关正常工作。我的 post 和 get 方法工作正常。但是,我需要支持 CORS。我的应用程序应该向 OPTIONS 请求返回正确的 CORS 响应,但它在 AWS 上不起作用。

最终,无论我做什么,我都会收到对选项请求的 500 响应。我无法弄清楚如何获取有关这 500 个错误的任何信息。我不确定是什么原因造成的。

这是 500 响应 {"message": "Internal server error"} 的正文。

这些是响应标头:

内容长度:36

内容类型:应用程序/json

日期:2017 年 7 月 9 日星期日 17:56:24 GMT

状态:500

通过:1.1 9af17e5a616bfc9ac07fc7e415ade9e6.cloudfront.net (CloudFront)

x-amz-cf-id:1_AZmkLqf1rjkog2MRtvcBAe54aIZdPWmNApBTwG48Af-v_g9WHkZw==

x-amzn-requestid:ec216a62-64cf-11e7-ad2b-4f1e96508dba

x-cache:来自云端的错误

我很确定我的 OPTIONS 请求甚至没有到达 Lambda 上的应用程序。

我已尝试使用 API 网关(以及在我的应用程序中)配置 CORS。我正在尝试将其配置为允许所有来源。

如果我可以查看或做些什么来调试此问题?

编辑:

为了调试此问题,我尝试在 CloudWatch 中为 API 网关启用日志记录。

完成此操作后,我在 CloudWatch 中看到这两个类似于网关的日志:

我一直在使用 prod,所以我点击那个链接并看到了这个:

我认为这是一长串日志条目。我不确定在这种情况下“流”是什么意思。有数百个这样的条目。因此,我选择具有最新时间戳的那个并单击它。现在我看到了:

看来我所有的网关日志都是这样的。 IE:显然是空的。

那么,我是否正确设置了日志记录?我找对地方了吗?

【问题讨论】:

  • 500 错误正文中的内容是什么?
  • 正文中唯一的内容是:{"message": "Internal server error"}
  • 我已经用我从 Chrome 中提取的更多细节更新了这个问题。
  • 确切的错误“内部服务器错误”将记录在您可以在舞台上启用的 cloudwatch 日志中。注意,如果 API 有任何配置错误,将会返回“Internal server error”。这种行为是因为 API 使用者将是您的用户,他们不应该真正看到有关您的 API 的任何调试信息。
  • 我不清楚如何将 CloudWatch 与 API 网关一起使用。我在设置中的“CloudWatch 日志角色 ARN”下添加了一个 ARN。但是,当我这样做时,我无法理解 CloudWatch 中显示的内容。我什至不确定我正在寻找正确的东西。我将在上面添加有关日志记录的更多详细信息。

标签: node.js amazon-web-services aws-lambda aws-api-gateway


【解决方案1】:

对我来说,解决办法是改变:

cors: true

cors:
  origin: '*'

我不确定有什么区别,但一个给我内部服务器错误,另一个没有。

【讨论】:

  • 为我工作,虽然只是删除 yml 上的 cors 标志也可以。重点是通过 express .use(..) 设置 cors
【解决方案2】:

我和@scopchanov 有类似的问题。

在我的 AWS Lambda + API Gateway + Serverless Framework 1.42.3 + Express.js 项目中起作用的是:

  1. 我必须启用 CORS / 从 Express 发送标头:

    // AWS API Gateway CORS (OPTIONS) 支持有问题? app.use(cors({credentials: true})); app.options("*", cors());

  2. 不要在 API Gateway 中启用 CORS,即不要在 serverless.yml 中执行此操作:

    • http: 方法:任何 路径:'{proxy+}' # 会导致 {"message": "Internal server error"} # cors: 真

没有cors: true,所有请求都可以正常工作。

使用cors: trueOPTIONS 请求将以{"message": "Internal server error"} 响应(不管 Lambda 函数做什么,这似乎是由 API Gateway 直接发送的,或者是有缺陷的 MOCK 集成)。

【讨论】:

  • 我设置了和你一样的选项,但偶尔会出现“内部服务器错误”。我不知道该怎么办...?
【解决方案3】:

对于那些仍然面临aws-serverless-express OPTIONS 500 错误的人,解决方案是将contentHandling: CONVERT_TO_TEXT 添加到Swagger template 中的OPTIONS 方法中

这是包含 //{proxy+} 路径的 swagger 模板文件

---
swagger: 2.0
info:
  title: AwsServerlessExpressApi
basePath: /prod
schemes:
- https
paths:
  /:
    x-amazon-apigateway-any-method:
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
        uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:${stageVariables.ServerlessExpressLambdaFunctionName}/invocations
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-amazon-apigateway-integration:
        contentHandling: CONVERT_TO_TEXT
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
  /{proxy+}:
    x-amazon-apigateway-any-method:
      produces:
      - application/json
      parameters:
      - name: proxy
        in: path
        required: true
        type: string
      responses: {}
      x-amazon-apigateway-integration:
        uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:${stageVariables.ServerlessExpressLambdaFunctionName}/invocations
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-amazon-apigateway-integration:
        contentHandling: CONVERT_TO_TEXT
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
x-amazon-apigateway-binary-media-types:
  - '*/*'
definitions:
  Empty:
    type: object
    title: Empty Schema

更多信息可以在 GitHub 上找到Internal server error when request method OPTIONS

希望这会有所帮助!

【讨论】:

    【解决方案4】:

    我在使用 cloudformation 创建无服务器解决方案时遇到了同样的问题。 Cloudformation 创建 API Gateway + Lambda,一切看起来都还不错。但是 OPTIONS 请求返回内部服务器错误。

    我只需要访问 API Gateway 并手动发布我的 API 一次。 (即使它已经发布到 prod 阶段)然后 OPTIONS 请求起作用了。我现在可以使用 cloudformation 进行更新了。

    【讨论】:

      【解决方案5】:

      您可以在路线索引文件中使用以下代码

      app.options(function(req,res){res.send(200);})
      

      这里的app是express的router对象。这会将所有的options请求发送到200。

      【讨论】:

      • 我删除了我对 cors 包的使用并添加了这个没有效果。我可以证明 get/post 请求进入我的 API,但我认为选项请求根本不存在: // 使所有选项请求返回 200 app.options('', (req, res) = > { console.log('FSsdfafsadfdsa'); res.append('Access-Control-Allow-Origin', ''); res.sendStatus(200); });
      【解决方案6】:

      我刚刚经历了这个......隐藏在 AWS lambda 文档中启用 CORS 的事实是,您必须在 lambda 中设置 CORS 标头。所以这里是如何做到这一点:

      let payload = {
          statusCode: 400,
          body: JSON.stringify('body'),
          headers: {"Access-Control-Allow-Origin": "*"} // NEED this for API CORS access
      };
      callback(null, payload);
      

      您必须返回有效的 statusCode 和正文以及标头,否则 API 将无法将您的 lambda 响应转换为 API 响应。

      【讨论】:

      • 不幸的是,我已经在 J​​avaScript 中得到了(我认为)相等:app.use( cors({ origin: '*' }) );
      • 我也是手动完成的,没有使用 cors 库,即使我手动实现了一个 OPTIONS 端点,我在 lambda 日志中也看不到任何内容。
      • 不一样。这是 javascript,忽略 IRepsonsePayload,这只是 TypeScript 类型。您必须将标头传回: headers: {"Access-Control-Allow-Origin": "*"}
      猜你喜欢
      • 2021-05-18
      • 1970-01-01
      • 1970-01-01
      • 2017-09-27
      • 2020-05-02
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      • 2015-11-08
      相关资源
      最近更新 更多