发出 OPTIONS 请求时出现 AWS API 网关错误

Posted

技术标签:

【中文标题】发出 OPTIONS 请求时出现 AWS API 网关错误【英文标题】:AWS API gateway error while making OPTIONS request 【发布时间】:2019-09-04 03:07:24 【问题描述】:

我正在使用 CFT 为我的 API 创建环境。我为 CORS 添加了 OPTIONS。我注意到当我从AWS console for OPTIONS 进行测试时,我收到了200 的响应。但是,当我从CURL or PostMan 执行相同操作时,我收到500 内部服务器错误。在审查了与之相关的 SO 问题之后。我已将集成响应修改为 CONVERT_TO_TEXT。但这也没有解决问题。

我注意到日志中有一个有线行为。以下是来自 AWS 控制台的请求的日志 sn-p:

Sat Apr 13 15:06:26 UTC 2019 : Method request headers:  Access-Control-Request-Method= POST, Content-Type= application/json
Sat Apr 13 15:06:26 UTC 2019 : Method request body before transformations: 
Sat Apr 13 15:06:26 UTC 2019 : Method response body after transformations: 
Sat Apr 13 15:06:26 UTC 2019 : Method response headers: X-Requested-With=*, Access-Control-Allow-Headers=Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-requested-with, Access-Control-Allow-Origin=*, Access-Control-Allow-Methods=POST,OPTIONS, Content-Type=application/json
Sat Apr 13 15:06:26 UTC 2019 : Successfully completed execution
Sat Apr 13 15:06:26 UTC 2019 : Method completed with status: 200

但是当我从 CRUL 或 PM 发出相同的请求时,我看到了以下日志:

Method request path: 
Method request query string: 
Method request headers:  Method request headers: Accept=*/*, CloudFront-Viewer-Country=IN, CloudFront-Forwarded-Proto=https, CloudFront-Is-Tablet-Viewer=false, CloudFront-Is-Mobile-Viewer=false, User-Agent=curl/7.55.1, X-Forwarded-Proto=https, CloudFront-Is-SmartTV-Viewer=false, Host=MYHOST, X-Forwarded-Port=443,   (CloudFront), Access-Control-Request-Method=POST, CloudFront-Is-Desktop-Viewer=true, Content-Type=application/json
Method request body before transformations: [Binary Data]
Execution failed due to configuration error: Unable to transform request
Method completed with status: 500

我们可以看到它正在尝试转换[Binary Data],但我没有发送任何内容。

我使用的卷曲:curl -X OPTIONS -H "Access-Control-Request-Headers: Content-Type" -H "Access-Control-Request-Method: POST" -H "Access-Control-Allow-Origin: '*'" -v MYHOST

为什么我在日志中看到这种差异?我的配置出了什么问题?你能帮帮我吗?

更新:我正在使用以下 CFT

Type: AWS::ApiGateway::Method
Properties:
  AuthorizationType: NONE
  HttpMethod: OPTIONS
  Integration:
    Type: MOCK
    IntegrationResponses:
    - StatusCode: 200
      ResponseParameters:
        method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
        method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
        method.response.header.Access-Control-Allow-Origin: "'*'"
    RequestTemplates:
      application/json:
        Fn::Join:
        - ''
        - - ""
          - ' "statusCode":200 '
          - ""
  MethodResponses:
  - StatusCode: 200
    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

【问题讨论】:

尝试删除 '-H "Content-Type: application/json"'。您的浏览器不会在 OPTIONS 请求中发送 Content-Type 标头。 (它只在 POST 请求中发送。)您还需要发送 Access-Control-Request-Headers 请求标头。 嗨@sideshowbarker - 我试过了,但仍然是同样的错误 ***.com/q/44067102/441757 看起来很相关。如果您发布您的 x-amazon-apigateway-integration 值,并且如果您发布您用于 OPTIONS 请求的模板,您似乎可以获得更好的帮助。另外,要明确一点:当您使用 curl 或 Postman 测试 POST 请求时,您不会遇到同样的失败吗?另见forums.aws.amazon.com/thread.jspa?threadID=256140 @sideshowbarker - 请参阅我帖子中的更新部分。 @backtrack 你解决了吗?如果是这样,您能否回答您的问题,详细说明您是如何解决此问题的。谢谢。 【参考方案1】:

似乎需要将contentHandling: CONVERT_TO_TEXT 参数添加到以下两者的记录较少:集成请求和集成响应设置。

在 swagger CORS 配置中看起来像这样:

responses: 
  200: 
    description: "Returning CORS headers",
    headers: 
      "Access-Control-Allow-Headers": type: "string" ,
      "Access-Control-Allow-Methods":  type: "string" ,
      "Access-Control-Allow-Origin":  type: "string" ,
    
  
,
"x-amazon-apigateway-integration": 
  type: "mock",
  contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
  requestTemplates: 
    "application/json": " \"statusCode\": 200 "
  ,
  responses: 
    "default": 
      statusCode: "200",
      contentHandling: "CONVERT_TO_TEXT", // Resolves problems with cloudfront binary content issues
      responseParameters: 
        "method.response.header.Access-Control-Allow-Headers": "'*'",
        "method.response.header.Access-Control-Allow-Methods" : "'*'",
        "method.response.header.Access-Control-Allow-Origin" : "'*'"
      ,
      responseTemplates: 
        "application/json": ""
      
    
  

【讨论】:

感谢一百万!我遇到了非常相似的问题,您的回答为我指明了正确的方向!我删除了二进制媒体类型*/*,并且 MOCK 在解析预检时不再失败!【参考方案2】:

如果在您的 API 网关设置中您已将“应用程序/json”添加到二进制媒体类型(例如,如果您想要 gzip 响应),或者如果此请求是针对二进制媒体类型的,则添加的默认 OPTIONS需要调整“启用 CORS”功能。

就像上面所说的那样,您至少需要将 contentHandling 设置为“CONVERT_TO_TEXT”以进行集成。对我来说,它无需将其添加到集成响应中即可工作。您可以通过 AWS CLI 执行以下操作:

aws apigateway update-integration --rest-api-id YOUR_REST_ID --resource-id YOUR_RESOURCE_ID --http-method OPTIONS --patch-operations op='replace',path='/contentHandling',value='CONVERT_TO_TEXT'

哦,以后别忘了重新部署 API。

【讨论】:

以上是关于发出 OPTIONS 请求时出现 AWS API 网关错误的主要内容,如果未能解决你的问题,请参考以下文章

向公共 API 发出请求时出现“无 'Access-Control-Allow-Origin' 标头”错误

向 Spotify API 发出 PUT 请求时出现 401 错误

发出 Axios GET 请求时出现无限循环 - 循环不会关闭

发出获取请求时出现多个问号

错误:使用 Fetch API 向第三方 API 发出 GET 请求时出现“TypeError:无法获取”

从 asp.net 核心应用程序发出 DELETE 请求时出现 405 错误