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

标签 aws-lambda axios aws-api-gateway serverless-framework 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.
在 Insomnia 中查询 Lambda 端点会返回一个带有 { "message": "internal server error" } 的 502 响应。 .但是执行 serverless invoke来自终端的 Lambda 函数的命令成功返回 Stripe 数据。
我正在为 serverless.yml 文件中的函数启用 cors,包括 'Access-Control-Allow-Origin': '*'在我的 Lambda 代码响应中,如 this Serverless blog post 中所述,我还尝试根据在 this issue on Axios 上找到的建议将以下 header 的各种组合添加到我的 Lambda 响应和我的 Axios 请求中。和 this issue on Serverless .我已多次删除并重新部署该服务
Lambda 响应 header
headers: {
      'Access-Control-Expose-Headers': 'Access-Control-Allow-Origin',
      'Access-Control-Allow-Credentials': true,
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*',
    },
react /Axios 配置
  {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    crossDomain: true
  }
目前我的代码如下:
react 应用
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);
}
lambda
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);
}
无服务器.yml
service: srd

provider:
  name: aws
  runtime: nodejs6.10
  stage: ${opt:stage, self:custom.defaultStage}
  region: eu-west-1
  memorySize: 256
  timeout: 6
  versionFunctions: true

plugins:
  - serverless-plugin-optimize
  - serverless-plugin-scripts

package:
  individually: true

functions:
  get-products:
    handler: lambda/get-products.handler
    name: srd-get-products-${self:provider.stage}
    description: 'get srd products from stripe'
    environment:
      STRIPE_PUBLISHABLE_KEY: ${self:custom.stripe_publishable_key.${self:provider.stage}}
      STRIPE_SECRET_KEY: ${self:custom.stripe_secret_key.${self:provider.stage}}
    events:
      - http:
          path: products
          method: get
          cors: true

custom:
  defaultStage: dev
  stripe_publishable_key:
    dev: ${file(env.yml):STRIPE_DEV_PUBLISHABLE_KEY}
    live: ${file(env.yml):STRIPE_LIVE_PUBLISHABLE_KEY}
  stripe_secret_key:
    dev: ${file(env.yml):STRIPE_DEV_SECRET_KEY}
    live: ${file(env.yml):STRIPE_LIVE_SECRET_KEY}
我已经在这里工作了几个小时,任何见解都非常感谢。
编辑/附加
从 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==

最佳答案

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

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

查看您的服务器并确保它正常运行。一旦 502 错误被修复,再试一次,你应该很高兴。尝试制作手册 OPTIONS请求,类似于浏览器会发出的请求,看看你是否得到同样的错误。

关于aws-lambda - 无服务器 Lambda 和 API 网关的 CORS 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49352041/

相关文章:

aws-lambda - 如何修改实时 Alexa 技能?

typescript - 使用 Nest.js 在 AWS Lambda 中获取 Cognito 数据(即 requestContext)

amazon-web-services - 如何获得从 AWS Lambda 到 Redis 的安全访问?是否需要 VPC?

aws-lambda - 如果 VTL/API 网关模板中不存在 key,则返回 null

android - 如何将aws api网关实现到android中?

amazon-web-services - 如何检查 AWS STS 访问 token 是否有效

javascript - 使用 Node.js 将多个图像写入磁盘

laravel - Vue axios 向错误的 URL 发出请求

reactjs - 无法在 axios 中设置 header

amazon-web-services - API网关自定义域证书错误