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

AWS API Gateway与Next.js交互时的CORS错误排查求助

解决Next.js调用AWS API Gateway的CORS跨域问题

错误信息

Access to fetch at 'https://xxxxxx.execute-api.us-east-1.amazonaws.com/items' from origin 'http://localhost:3000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

现有配置与代码

1. API Gateway配置

API Gateway配置截图

2. Lambda函数代码

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { DynamoDBDocumentClient, ScanCommand, PutCommand, GetCommand, DeleteCommand } from "@aws-sdk/lib-dynamodb";

const dynamoDBClient = new DynamoDBClient({});
const s3Client = new S3Client({});
const client = new DynamoDBClient({});
const dynamoDBDocumentClient = DynamoDBDocumentClient.from(dynamoDBClient);

const dynamo = DynamoDBDocumentClient.from(client);

const tableName = " ";
const s3BucketName = "";

export const handler = async (event) => {
  const response = {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Headers": "rid,fdi-version,anti-csrf,st-auth-mode",
      "Access-Control-Allow-Origin" : "*",
      "Access-Control-Allow-Methods": "OPTIONS,POST,GET, PUT",
       "Cache-Control": "max-age=0, no-store, must-revalidate",
       "Access-Control-Allow-Credentials": "true",

    },
    body: "",
  };

  try {
    switch (event.routeKey) {
      case "POST /items":
       
        break;

      case "GET /items":
        
        break;

      case "GET /items/{id}":
       
        break;

      case "DELETE /items/{id}":
        
        break;

      default:
        throw new Error(`Unsupported route: "${event.routeKey}"`);
    }
  } catch (err) {
    response.statusCode = 400;
    response.body = err.message;
  }

  return response;
};

// Function to generate a random alphanumeric string

3. Next.js handleSubmit代码

const handleSubmit = async (event) => {
  event.preventDefault();

    var myHeaders = new Headers();
    myHeaders.append("Content-Type", "application/json");
    
    var raw = JSON.stringify({
      "id": formData.projectId,
      "projectName": formData.projectName,
      "clientName": formData.clientName,
      
    });
    
    var requestOptions = {
      method: 'POST',
      headers: myHeaders,
      body: raw,
      redirect: 'follow',
      // mode: 'no-cors',
    };
    
    fetch("https://xxxxxxx.execute-api.us-east-1.amazonaws.com/items", requestOptions)
       .then(response => console.log(response.json()))
       .then(result => console.log(result, 'resulttttt'))
       .catch(error => console.log('error', error))

};

排查与解决方案

1. 处理OPTIONS预请求

浏览器发起跨域POST请求前会先发送OPTIONS预请求,需确保该请求能正确返回CORS头。在Lambda的switch语句中添加OPTIONS分支:

case "OPTIONS /items":
  // 直接返回配置好的CORS响应
  break;

若API Gateway使用Lambda代理集成,需确认OPTIONS请求能触发Lambda并返回响应。

2. 修正允许的请求头

你的Next.js请求使用了Content-Type: application/json,但当前Lambda的Access-Control-Allow-Headers未包含该字段,会导致预请求失败。修改Lambda的响应头:

"Access-Control-Allow-Headers": "rid,fdi-version,anti-csrf,st-auth-mode,Content-Type",

同时在API Gateway的CORS配置中,将Content-Type添加到允许的头列表,修改后必须重新部署API Gateway才会生效。

3. 解决CORS配置冲突

你同时设置了Access-Control-Allow-Origin: *和Access-Control-Allow-Credentials: true,这两个配置冲突:当允许凭证(如Cookie)时,Origin不能使用通配符,必须指定具体域名。

二选一处理:

  • 若不需要凭证:删除Access-Control-Allow-Credentials: true
  • 若需要凭证:将Access-Control-Allow-Origin改为具体域名,开发环境用http://localhost:3000,生产环境替换为实际域名

4. 验证API部署

每次修改API Gateway的CORS配置或Lambda代码后,都需要重新部署API,确保新配置生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 02:20:45