无服务器 Lambda 和 API 网关的 CORS 问题

Jos*_*osh 5 aws-lambda aws-api-gateway serverless-framework axios http-status-code-502

解决了

以下问题只是由我的 Lambda 中构造的响应对象的 body 属性引起的。我忘记对数据进行字符串化,body: data而不是返回body: JSON.stringify(data). 这个响应问题似乎触发了 API Gateway 的错误,导致请求失败并出现一些相当混乱的错误消息。

问题

我正在使用 React、Serverless 和 Stripe API 开发电子商务网站。我的前端 React 应用程序正在使用 Axios 向我的 Lambda 函数发出 GET 请求,该函数已通过 API 网关公开。Lambda 函数依次查询 Stripe API 并将 Stripe 响应数据返回给我的 React 应用程序。但是,当我的 React 应用程序尝试调用 Lambda 时,我遇到了 CORS 问题,它收到以下错误:

Failed to load: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 502.
Run Code Online (Sandbox Code Playgroud)

在 Insomnia 中查询 Lambda 终端节点会返回 502 响应{ "message": "internal server error" }。但是serverless invoke从终端执行Lambda 函数的命令成功返回了 Stripe 数据。

我正在为 serverless.yml 文件中的函数启用 cors,并'Access-Control-Allow-Origin': '*'按照此无服务器博客文章中的建议将其包含在我的 Lambda 代码响应中,我还尝试将以下标头的各种组合添加到我的 Lambda 响应和我的 Axios 请求基于建议上找到关于爱可信这一问题,并在无服务器这个问题。我已多次删除并重新部署该服务

Lambda 响应标头

Failed to load: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 502.
Run Code Online (Sandbox Code Playgroud)

反应/Axios 配置

headers: {
      'Access-Control-Expose-Headers': 'Access-Control-Allow-Origin',
      'Access-Control-Allow-Credentials': true,
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*',
    },
Run Code Online (Sandbox Code Playgroud)

目前我的代码如下:

反应应用

  {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    crossDomain: true
  }
Run Code Online (Sandbox Code Playgroud)

拉姆达

import Axios from 'axios';
import { GET_PRODUCTS_URL } from '../config';

export default () => {
  return Axios
  .get(GET_PRODUCT_URL, {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    crossDomain: true
  })
  .then(({ data }) => data)
  .catch(console.log);
}
Run Code Online (Sandbox Code Playgroud)

无服务器.yml

import Stripe from 'stripe';
const apiKey = process.env.STRIPE_SECRET_KEY;

const stripe = Stripe(apiKey);

module.exports.handler = (event, context, callback) => {
  return stripe.products
    .list()
    .then(({ data }) => {
      const response = {
        statusCode: 200,
        headers: {
          'Access-Control-Expose-Headers': 'Access-Control-Allow-Origin',
          'Access-Control-Allow-Credentials': true,
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
        },
        body: data,
      };
      callback(null, response);
    })
    .catch(console.log);
}
Run Code Online (Sandbox Code Playgroud)

我已经在这里工作了几个小时,任何见解都非常感谢。

编辑/附加 从 CLI 发出选项请求将返回以下内容:

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 0
Connection: keep-alive
Date: Mon, 19 Mar 2018 06:52:12 GMT
x-amzn-RequestId: 0d10c9d1-2b42-11e8-b270-a723e367048e
Access-Control-Allow-Origin: *
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,GET
Access-Control-Allow-Credentials: false
X-Cache: Miss from cloudfront
Via: 1.1 e40b14deb4a844594f746b751f632677.cloudfront.net (CloudFront)
X-Amz-Cf-Id: eMvu3Ke7m7GNFCFgIOGVJmoObFwYMeEt4o8AByoipfMn1nXIi9Vo0g==
Run Code Online (Sandbox Code Playgroud)

Lan*_*ara 3

CORS 错误消息中的 HTTP 响应代码为 502。这意味着您请求的服务器不可用。

如果出现 502,浏览器将无法成功发出OPTIONS请求,因此即使您在服务器中的 CORS 设置正确,您仍然会收到 CORS 错误,因为它没有得到正确解决。

查看您的服务器并确保它正常运行。修复 502 错误后,再试一次,您应该就可以开始了。尝试发出OPTIONS类似于浏览器发出的手动请求,并查看是否收到相同的错误。

  • 啊,所以 API GW 收到了 Lambda 的响应,它在处理时遇到了问题,这在 502 错误描述的上下文中是有意义的“502 Bad Gateway 服务器错误响应代码表明服务器在充当网关或代理时,从上游服务器收到无效响应。” (4认同)
  • 我现在已经解决了这个问题,尽管我不完全理解我收到的错误和响应之间的关系。具体来说,这是我在 Lambda 中返回的响应对象的 body 属性的问题,我返回了“body: data,”,而我应该返回“body: JSON.stringify(data),”。感谢您的帮助。 (2认同)