【问题标题】:502 bad gateway error for cross-origin request502 跨域请求的网关错误
【发布时间】:2019-10-07 11:13:02
【问题描述】:

我正在使用serverless 框架将我的 lambda 部署到 AWS,并且能够通过 Postman 成功地将 POST 请求运行到与我的 lambda 函数关联的 API 网关,但是当我尝试从表单提交运行 POST 请求时(AJAX 请求)在本地服务器上我收到 502 错误消息,

Access to XMLHttpRequest at 'https://*id*.execute-api.us-east-1.amazonaws.com/prod/message' from origin 'http://localhost:2368' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是我没想到的,因为我将 serverless.yml 中的 cors 属性设置为 true,它为 HTTP 端点设置了 CORS 配置。这是yaml设置的功能:

functions:
  email:
    handler: handler.sendEmail
    events:
      - http:
          path: message
          method: post
          cors: true

这里是 jQuery AJAX 请求:

$.ajax({
    type: 'POST',
    url: 'https://*id*.execute-api.us-east-1.amazonaws.com/prod/message',
    crossDomain: true,
    data: JSON.stringify(formData),
    contentType: 'application/json',
    dataType: 'json',
    success: function(data) {
        console.log(data)
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log(xhr);
        console.log(ajaxOptions);
        console.log(thrownError);
    }
});

我需要使用 API Gateway 配置或在我的 Lambda 应用程序中进行调整吗?

这是我的响应函数:

const generateResponse = (body, statusCode) => {
  console.log("generateResponse")
  console.log(body)
  return Promise.resolve({
      headers: {
          "access-control-allow-methods": "POST",
          "access-control-allow-origin": "*",
          "content-type": "application/json",
      },
      statusCode: statusCode,
      body: `{\"result\": ${body.message}}`
  });
};

还提供了ajax请求:

$.ajax({
    type: 'POST',
    url: 'https://*my-lambda-id*.execute-api.us-east-1.amazonaws.com/prod/message',
    crossDomain: true,
    data: JSON.stringify(formData),
    contentType: 'application/json',
    dataType: 'json',
    success: function(data) {
        console.log(data)
    },
    error: function(xhr, ajaxOptions, thrownError) {
        console.log(xhr);
        console.log(ajaxOptions);
        console.log(thrownError);
    }
})

以及由 AJAX 触发的 OPTION 和 POST 请求和响应标头:

选项:

Request URL: https://*my-lambda-id*.execute-api.us-east-1.amazonaws.com/prod/message
Request Method: OPTIONS
Status Code: 200 

Response Headers
access-control-allow-credentials: false
access-control-allow-headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent
access-control-allow-methods: OPTIONS,POST
access-control-allow-origin: http://localhost:2368
content-length: 1
content-type: application/json
date: Tue, 08 Oct 2019 11:11:36 GMT
status: 200
via: 1.1 *id*.cloudfront.net (CloudFront)
x-amz-apigw-id: *id*
x-amz-cf-id: *id*
x-amz-cf-pop: *id*
x-amzn-requestid: *id*
x-cache: Miss from cloudfront

Request Headers
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Origin: http://localhost:2368
Referer: http://localhost:2368/
Sec-Fetch-Mode: no-cors

发布

Request URL: https://*my-lambda-id*.execute-api.us-east-1.amazonaws.com/prod/message
Request Method: POST
Status Code: 502 

Request Headers
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/json
Origin: http://localhost:2368
Referer: http://localhost:2368/
Sec-Fetch-Mode: cors

【问题讨论】:

  • 您收到 502 错误的事实是真正的问题。任何 5xx 错误都不会有任何 CORS 标头。因此,当您遇到 502 错误时,预计浏览器也会记录 CORS 错误。但这并不意味着您有 CORS 问题。如果您修复了 502 错误的原因,那么您可能会发现您的 CORS 配置实际上按预期工作。
  • @sideshowbarker 感谢您的解释和指导。我将我的 ajax 请求和标题添加到我的问题中。您是否认为 ajax 配置可能是 502 的原因
  • 尽量不返回承诺。只是响应对象
  • 另外,您的 POST 请求显示 502 shich 与 CORS 无关。如果 AWS 由于某些错误(例如 Promise 未解析请求)而生成 502,则不会有 CORS 标头,因此您也会看到 CORS 错误。如果你修复了 502,我很确定你不会出现 CORS 错误

标签: ajax aws-lambda aws-api-gateway serverless-framework


【解决方案1】:

无论您从 Lambda 函数返回响应的何处,都需要包含特定标头 CORS 请求。您添加到 serverless.yml 的 cors: true 选项仅有助于确保 OPTIONS 飞行前请求有效。不要忘记这也包括不成功的响应。

例如:

return {
    statusCode: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Credentials': true,
      'Access-Control-Allow-Headers': 'Authorization'
    }
  }

【讨论】:

  • 我更新了我的问题以添加到我一直使用的响应标头中。我对其进行了修改以包含您提到的其他标准,但我仍然收到相同的错误。当我通过无服务器离线运行此功能时,我收到了正确的响应,但尽管功能运行成功,但在 AWS(生产)中收到内部错误。我很好奇这是否是我看到的错误的一个因素
  • @cphill 你没有包括 ACAC。它是 cookie 访问所必需的。或使用withCredentials : false
  • 我更新了问题以包括我收到的OPTIONSPOST 请求和响应,以及我正在使用的ajax。会不会和我做的ajax请求配置有关?
  • @SagarV 在问题中提供的代码中设置在哪里?
  • 有问题的是,响应选项的 ACAC 是错误的(这是默认值)。将其设置为真。在服务器响应中添加“access-control-allow-credentials: true”。
猜你喜欢
  • 1970-01-01
  • 2019-01-09
  • 2018-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 2014-06-25
相关资源
最近更新 更多