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

AWS Lambda与API Gateway HTTP API的CORS问题排查

使用AWS API Gateway HTTP API调用Lambda时的CORS错误排查

配置信息

API Gateway 配置

类型:HTTP API(非REST API)

CORS 设置

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, POST
Access-Control-Allow-Headers: Content-Type

Lambda 函数代码

const AWS = require('aws-sdk');
const ses = new AWS.SES({ region: 'us-east-1' });

exports.handler = async (event) => {
  const headers = {
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'POST, OPTIONS',
    'Access-Control-Allow-Headers': 'Content-Type',
    'Access-Control-Max-Age': '3600', // 缓存1小时
  };

  if (event.httpMethod === 'OPTIONS') {
    return {
      statusCode: 200,
      headers: headers,
      body: '',
    };
  }

  if (event.httpMethod === 'POST') {
    const { name, email, message } = JSON.parse(event.body);

    const params = {
      Destination: {
        ToAddresses: ['email'], // 替换为已验证的邮箱地址
      },
      Message: {
        Body: {
          Text: {
            Charset: 'UTF-8',
            Data: `Name: ${name}\nEmail: ${email}\nMessage: ${message}`,
          },
        },
        Subject: {
          Charset: 'UTF-8',
          Data: 'New Contact Form Submission',
        },
      },
      Source: 'xxx@gmail.com', // 替换为已验证的邮箱地址
    };

    try {
      await ses.sendEmail(params).promise();
      return {
        statusCode: 200,
        headers: headers,
        body: JSON.stringify({ message: '消息发送成功!' }),
      };
    } catch (error) {
      console.error(error);
      return {
        statusCode: 500,
        headers: headers,
        body: JSON.stringify({ message: '消息发送失败。' }),
      };
    }
  }

  return {
    statusCode: 405,
    headers: headers,
    body: JSON.stringify({ message: '不允许的请求方法' }),
  };
};

问题现象

提交表单时持续收到CORS错误:

Access to fetch at 'https://cl4dhs3yg7.execute-api.us-east-1.amazonaws.com/dev/contact' from origin 'http://example.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

已执行的排查步骤

  • 确认Lambda函数在OPTIONS和POST响应中都包含CORS头部
  • 验证API Gateway的CORS配置正确
  • 修改配置后重新部署API
  • 使用CURL测试预检请求和实际请求,但预检请求无输出

预检请求命令

curl -i -X OPTIONS https://cl4dhs3yg7.execute-api.us-east-1.amazonaws.com/dev/contact \
-H "Origin: http://example.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Content-Type"

实际POST请求命令

curl -i -X POST https://cl4dhs3yg7.execute-api.us-east-1.amazonaws.com/dev/contact \
-H "Origin: http://example.com" \
-H "Content-Type: application/json" \
-d '{"name":"hari", "email":"hari987@gmail.com", "message":"test message"}'

补充信息

使用的是API Gateway HTTP API而非REST API;未配置特定参数映射。


问题原因及解决方案

可能的原因

  1. HTTP API的CORS配置未关联目标路由
    HTTP API的CORS设置需要明确绑定到对应的路由(如/dev/contact),仅全局开启CORS但未关联目标路由时,预检请求无法触发正确的CORS响应。
  2. OPTIONS方法未正确配置到路由
    若API Gateway的/dev/contact路由未添加OPTIONS方法,或该方法未指向Lambda函数,预检请求会被API Gateway直接拦截,无法触发Lambda返回CORS头部。
  3. 部署未生效
    修改配置后未重新部署API,导致新的CORS设置未同步到生产环境。

解决方案

1. 绑定CORS配置到目标路由

  • 进入AWS控制台的API Gateway,找到目标HTTP API
  • 进入CORS设置页面,确认/dev/contact已添加到关联路由列表;或直接在/dev/contact路由的单独配置中开启CORS

2. 确认OPTIONS方法的路由配置

  • 检查/dev/contact路由的方法列表,确保包含OPTIONS和POST两种方法
  • 确认两种方法的集成目标均指向你的Lambda函数,避免OPTIONS请求被拦截

3. 优化Lambda的CORS头部(可选)

  • 若生产环境不允许使用通配符*,可将Access-Control-Allow-Origin设置为请求的Origin值,增强安全性:
    const origin = event.headers.origin || '*';
    const headers = {
      'Access-Control-Allow-Origin': origin,
      'Access-Control-Allow-Methods': 'POST, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
      'Access-Control-Max-Age': '3600',
    };
    

4. 重新部署并验证

  • 修改配置后,点击API Gateway中的部署按钮,推送更新到生产环境
  • 重新执行CURL预检请求,确认响应包含Access-Control-Allow-Origin等CORS头部,且状态码为200

5. 启用日志排查

  • 开启API Gateway的访问日志,查看预检请求的流向:是否到达Lambda、Lambda返回的响应是否包含CORS头部,定位问题节点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 12:44:55