You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AWS Lambda(SAM)与React时遭遇CORS错误求助

问题描述

开发React应用时,通过axios向AWS Lambda发送POST请求,使用SAM创建Lambda API与函数,按官方文档配置后,Postman测试API功能正常,但React本地运行及部署到Lightsail后均出现CORS错误,调试24小时未解决,需定位问题。

template.yml 配置

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  openai-site-parser-and-summary

  Sample SAM Template for openai-site-parser-and-summary

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,OPTIONS'"
      AllowOrigin: "'*'"
      AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
  Function:
    Timeout: 120
    LoggingConfig:
      LogFormat: JSON

Resources:
  MyApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Cors:
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
        AllowCredentials: "'*'"
        AllowMethods: "'*'"

  OpenAiSiteParserFunction:
    Type: AWS::Serverless::Function
    Properties:
      Environment:
        Variables:
          MY_API_KEY: "MY_API-KEY"
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.10
      Architectures:
        - x86_64
      Events:
        EndpointEvent:
          Type: Api
          Properties:
            RestApiId: !Ref MyApiGateway
            Path: /parse
            Method: post

  MyApiGatewayDeployment:
    Type: AWS::ApiGateway::Deployment
    DependsOn:
      - MyApiGateway
      - OpenAiSiteParserFunction
    Properties:
      RestApiId: !Ref MyApiGateway

  MyApiKey:
    Type: AWS::ApiGateway::ApiKey
    Properties:
      Enabled: true

  MyUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn:
      - MyApiGatewayDeployment
    Properties:
      ApiStages:
        - ApiId: !Ref MyApiGateway
          Stage: Prod
      Description: Usage plan for My API
      UsagePlanName: MyUsagePlan
      Throttle:
        BurstLimit: 100
        RateLimit: 50
      Quota:
        Limit: 10000
        Period: MONTH

  MyUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    Properties:
      KeyId: !Ref MyApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref MyUsagePlan

Outputs:
  OpenAiSiteParserApi:
    Description: "API Gateway endpoint URL for Prod stage"
    Value: !Sub "https://${MyApiGateway}.execute-api.${AWS::Region}.amazonaws.com/Prod/parse/"
  OpenAiSiteParserFunction:
    Description: "Lambda Function ARN"
    Value: !GetAtt OpenAiSiteParserFunction.Arn
  OpenAiSiteParserFunctionIamRole:
    Description: "Implicit IAM Role created for function"
    Value: !GetAtt OpenAiSiteParserFunctionRole.Arn

Lambda函数代码(app.py)

import json
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from openai import OpenAI

def lambda_handler(event, context):
    # 业务逻辑...
    return {
            "statusCode": 200,
            "headers": {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods": "*",
                "Access-Control-Allow-Headers": "*",
                "Access-Control-Allow-Credentials" : True
            },
            "body": json.dumps({
                "summary": final_summary
            })
        }

React端错误信息

Access to XMLHttpRequest at 'https://1234567890.execute-api.us-east-2.amazonaws.com/Prod/parse/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

已尝试的解决方法

尝试1:修改Lambda返回头

调整Lambda的响应头,简化为仅保留Access-Control-Allow-Origin:

def lambda_handler(event, context):
    # 业务逻辑...
    return {
            "statusCode": 200,
            "headers": {
                "Access-Control-Allow-Origin": "*"
            },
            "body": json.dumps({
                "summary": final_summary
            })
        }

查看Chrome Network面板发现:预检请求响应头包含CORS允许字段,但POST请求返回InternalServerErrorException。


问题定位与解决方案

核心问题分析

  1. CORS配置冲突:SAM模板中Globals.Api.Cors与MyApiGateway.Properties.Cors重复配置,且AllowCredentials取值错误(不能设为'*',仅支持true/false)。
  2. API密钥验证未处理:配置了API密钥和使用计划,但React请求未携带x-api-key头,导致请求被拦截返回500错误,浏览器因错误响应无CORS头,触发CORS报错。
  3. Lambda错误无CORS头:Lambda抛出内部异常时,默认不返回CORS头,掩盖真实错误,表现为CORS问题。

分步解决

1. 修复SAM模板CORS配置

删除重复的Globals.Api.Cors段,统一在MyApiGateway中正确配置:

Resources:
  MyApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Cors:
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
        AllowCredentials: false  # 无需凭证时设为false,需要则设为true
        AllowMethods: "'GET,POST,OPTIONS'"

2. 处理API密钥验证

  • 若无需API密钥:删除MyApiKey、MyUsagePlan、MyUsagePlanKey资源,在API方法设置中关闭API密钥要求。
  • 若保留API密钥:在React请求中添加x-api-key头:
axios.post('https://你的API地址/Prod/parse/', 请求数据, {
  headers: {
    'x-api-key': '你的API密钥'
  }
})

3. 确保Lambda异常时返回CORS头

修改Lambda代码,添加异常捕获,无论成功失败都返回CORS头:

import json
import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin, urlparse
from openai import OpenAI

def lambda_handler(event, context):
    try:
        # 业务逻辑...
        return {
            "statusCode": 200,
            "headers": {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
                "Access-Control-Allow-Headers": "*"
            },
            "body": json.dumps({
                "summary": final_summary
            })
        }
    except Exception as e:
        return {
            "statusCode": 500,
            "headers": {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods": "GET,POST,OPTIONS",
                "Access-Control-Allow-Headers": "*"
            },
            "body": json.dumps({
                "error": str(e)
            })
        }

4. 重新部署SAM应用

执行命令更新配置:

sam build
sam deploy --guided

内容的提问来源于stack exchange,提问作者Pythoner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 18:25:07