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

AWS API Gateway触发Lambda启用CORS后仍报500内部错误

问题排查:API Gateway调用Lambda返回500 Internal Server Error

问题现象

  • Lambda控制台测试可正常执行DynamoDB写入、SMS发送两项逻辑
  • 已在Lambda中配置CORS响应头,也在API Gateway控制台启用CORS并重新部署,但Postman、自有网站前端调用均返回错误
  • Postman调用返回内容:{"message": "Internal server error"}
  • 自有网站jQuery ajax POST调用返回500状态码,响应内容与Postman一致
  • 直接访问API Gateway提供的接口端点,同样返回上述500错误

根因说明

代码存在4个核心问题,直接导致API调用失败:

  1. 异步逻辑时序错误:dynamodb.putItem是异步非阻塞调用,发起调用后未等待执行完成就同步调用callback返回响应,异步操作的错误完全无法被捕获,API Gateway会因为Lambda执行上下文提前退出、返回结构不符合预期抛出通用500错误。
  2. Event结构解析错误:使用API Gateway Lambda代理集成时,POST请求的参数不会直接挂载在event根节点,而是序列化为JSON字符串存放在event.body字段中。控制台测试时使用的是自定义测试事件,参数直接放在根节点因此可以正常运行,但实际API转发的请求中event.Id、event.Type均为undefined,DynamoDB写入时会因为缺少必填主键直接报错。
  3. 异步写法失效:在DynamoDB回调函数中返回Promise没有实际作用,外层代码没有接收、等待该Promise执行,SNS发送逻辑的执行结果和抛出的错误完全不会被处理。
  4. 未处理跨域预检请求:浏览器发起跨域POST请求前会自动发送OPTIONS方法的预检请求,现有代码未对OPTIONS方法做特殊处理,会尝试解析不存在的请求体、执行DynamoDB写入逻辑直接触发报错。

修复方案

1. 替换Lambda代码

统一使用async/await处理异步逻辑,正确解析请求结构、处理预检请求、捕获全局错误,修复后代码如下:

const AWS = require('aws-sdk');
// 推荐使用DocumentClient,无需手动指定字段类型N/S,减少参数错误
const dynamodb = new AWS.DynamoDB.DocumentClient();
const SNS = new AWS.SNS();
const tableName = "#####";  
const snsParams = {
    PhoneNumber: 'mynumber####',
    Message: 'Someone wrote!'
};

exports.handler = async (event) => {
    // 统一配置CORS响应头,所有响应(包括错误响应)都需携带
    const corsHeaders = {
        "Access-Control-Allow-Headers" : "Content-Type",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
    };

    try {
        // 单独处理OPTIONS跨域预检请求
        if (event.httpMethod === 'OPTIONS') {
            return {
                statusCode: 200,
                headers: corsHeaders,
                body: ''
            };
        }

        // 解析API Gateway传递的JSON格式请求体
        const requestBody = JSON.parse(event.body || '{}');
        const { Id, Type } = requestBody;
        // 校验必填参数
        if (!Id || !Type) {
            return {
                statusCode: 400,
                headers: corsHeaders,
                body: JSON.stringify({error: 'Missing required parameters: Id or Type'})
            };
        }

        // 等待DynamoDB写入完成
        await dynamodb.put({
            TableName: tableName,
            Item: {
                Id: Number(Id),
                Type: Type
            }
        }).promise();
        console.log('Success in writing, now starting to send SMS');

        // 等待SNS短信发送完成
        await SNS.publish(snsParams).promise();
        console.log('SMS alarm sent!');

        // 正常返回响应
        return {
            statusCode: 200,
            headers: corsHeaders,
            body: JSON.stringify({message: 'Operation completed'})
        };

    } catch (err) {
        console.log('Execution error: ', err);
        // 错误响应也需携带CORS头,避免前端无法读取错误信息
        return {
            statusCode: 500,
            headers: corsHeaders,
            body: JSON.stringify({error: err.message})
        };
    }
};

2. 配置校验

  • 确认API Gateway集成类型为Lambda代理集成,如果使用非代理集成,需要在API Gateway侧单独配置响应映射模板,不能直接在Lambda中返回statusCode/headers/body结构
  • 修改配置后必须重新部署API到对应调用的stage(如dev/prod),仅保存配置不会生效
  • 发起POST请求时需要携带Content-Type: application/json请求头,请求体传递合法JSON结构,例如{"Id": 123, "Type": "test"}
  • 如果仍有报错,直接前往CloudWatch Logs查看对应Lambda调用的日志流,可获取具体错误栈,比API Gateway返回的通用500提示信息更精准

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:06:23