简体   繁体   English

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

[英]CORS issues with Serverless Lambda and API Gateway

Solved解决了

The below issue was simply caused by the body property of the response object constructed in my Lambda.以下问题只是由在我的 Lambda 中构建的响应对象的 body 属性引起的。 I was forgetting to stringify the data, returning body: data instead of body: JSON.stringify(data) .我忘记对数据进行字符串化,返回body: data而不是body: JSON.stringify(data) This problem with the response appeared to trigger an error with API Gateway which caused the request failures with some rather confusing error messages.这个响应问题似乎触发了 API 网关的错误,导致请求失败并出现一些相当混乱的错误消息。

Problem问题

I'm working on a ecommerce site using React, Serverless and the Stripe API.我正在使用 React、Serverless 和 Stripe API 开发电子商务网站。 My front-end React app is making a GET request using Axios to my Lambda function which has been exposed via API Gateway.我的前端 React 应用程序正在使用 Axios 向我的 Lambda 函数发出 GET 请求,该函数已通过 API 网关公开。 The Lambda function in turn queries the Stripe API and returns the Stripe response data to my React app. Lambda 函数依次查询 Stripe API 并将 Stripe 响应数据返回到我的 React 应用程序。 However, I am experiencing CORS issues as my React app tries to call the Lambda, it receives the following error:但是,当我的 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.

Querying the Lambda endpoint in Insomnia returns a 502 response with { "message": "internal server error" } .在 Insomnia 中查询 Lambda 端点会返回带有{ "message": "internal server error" }的 502 响应。 But executing the serverless invoke command from the Lambda function from the terminal successfully returns the Stripe data.但是从终端的 Lambda 函数执行serverless invoke命令成功返回 Stripe 数据。

I am enabling cors for the function in my serverless.yml file and including 'Access-Control-Allow-Origin': '*' in my Lambda code response as advised in this Serverless blog post , I have also attempted adding a various combinations of the following headers to my Lambda response and my Axios request based on suggestions found on this issue on Axios and this issue on Serverless .我正在为我的 serverless.yml 文件中的函数启用 cors,并按照无服务器博客文章中的建议在我的 Lambda 代码响应中包含'Access-Control-Allow-Origin': '*' ,我还尝试添加各种组合根据在 Axios 上的此问题和Serverless上的此问题上找到的建议,我的 Lambda 响应和 Axios 请求的以下标头。 I've deleted and redeployed the service multiple times and我已经多次删除并重新部署该服务,并且

Lambda response headers Lambda 响应标头

headers: {
      'Access-Control-Expose-Headers': 'Access-Control-Allow-Origin',
      'Access-Control-Allow-Credentials': true,
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*',
    },

React/Axios config反应/Axios 配置

  {
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    crossDomain: true
  }

Currently my code is as follows:目前我的代码如下:

React app反应应用程序

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);
}

Serverless.yml无服务器.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}

I've been at this for hours, any insights much appreciated.我已经在这里工作了几个小时,非常感谢任何见解。

Edit/Additional Making an options request from the CLI returns the following:编辑/附加从 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==

The HTTP response code in the CORS error message says 502. This means the server you are requesting is unavailable. CORS 错误消息中的 HTTP 响应代码为 502。这意味着您请求的服务器不可用。

In an event of a 502, the browser cannot make successful OPTIONS requests, so even if your CORS setup in the server is correct, you will still get a CORS error since it was not resolved properly.在 502 的情况下,浏览器无法发出成功的OPTIONS请求,因此即使您在服务器中的 CORS 设置正确,您仍然会收到 CORS 错误,因为它没有正确解析。

Look at your server and make sure it is running as it should.查看您的服务器并确保其正常运行。 Once the 502 error is fixed, try again and you should be good to go.一旦修复了 502 错误,请重试,您应该可以开始了。 Try making a manual OPTIONS request, similar to that of what the browser would make, and see if you get the same error.尝试手动发出OPTIONS请求,类似于浏览器发出的请求,看看是否会出现相同的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 放大与 Rest API 网关 lambda 集成 CORS 问题 - Amplify with Rest API Gateway lambda integration CORS issues Serverless API Gateway/Lambda 下载失败 PDF - Serverless API Gateway/Lambda fails to download PDF Terraform 无服务器应用程序与 AWS Lambda 和 API 网关未知令牌? - Terraform Serverless Applications with AWS Lambda and API Gateway unknown token? 是否可以使用 Serverless 在两个区域部署 API 网关和 Lambda? - Is it possible to deploy API Gateway and Lambda in two regions with Serverless? 无服务器 AWS Lambda CORS 错误 - Serverless AWS Lambda CORS Error GCP 上的无服务器 API 网关 - Serverless API Gateway on GCP CORS 错误,API 网关和 Lambda **仅**使用代理集成时 - CORS error with API Gateway and Lambda **only** when using Proxy Integration CORS 在 AWS 上不可能 Lambda HTTP API 网关集成 - CORS impossible on AWS Lambda HTTP API Gateway Integration Django 在无服务器上运行的应用程序 + Lambda + API 网关 HTTP API 正在重写链接以使用默认前缀 - Django application running on top of Serverless + Lambda + API Gateway HTTP API is rewriting links to be prefixed with default api网关和lambda分页 - api gateway and lambda pagination
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM