AWS API Gateway OPTIONS 请求返回 500 错误

Posted

技术标签:

【中文标题】AWS API Gateway OPTIONS 请求返回 500 错误【英文标题】:AWS API Gateway OPTIONS requests returns 500 error 【发布时间】: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 中显示的内容。我什至不确定我正在寻找正确的东西。我将在上面添加有关日志记录的更多详细信息。 【参考方案1】:

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

cors: true

cors:
  origin: '*'

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

【讨论】:

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

我和@scopchanov 有类似的问题。

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

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

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

    不要在 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": "*"

以上是关于AWS API Gateway OPTIONS 请求返回 500 错误的主要内容,如果未能解决你的问题,请参考以下文章

AWS API Gateway CORS 对 OPTIONS 正常,对 POST 失败

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

AWS Api Gateway 未在 204 上设置 CORS

AWS API Gateway CORS 飞行前检查失败

AWS S3 静态站点 CORS jquery ajax POST 到 API Gateway

如何使用 AWS Cloudformer 为现有 API Gateway 创建云形成模板?