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

NextJS 14部署AWS Amplify后Origin显示localhost:3000的CORS问题

问题:AWS Amplify部署NextJS 14.2.20后,Middleware获取的Origin异常为localhost:3000

现象

将NextJS 14.2.20应用通过GitHub部署至AWS Amplify后,服务器端CORS白名单校验时,req.nextUrl.origin获取到的值是https://localhost:3000,而非Amplify分配的应用域名(如https://main.xxxxxx.amplifyapp.com),导致校验失败返回405错误。

该问题仅在AWS Amplify部署时出现:

  • 本地运行(端口88888)时,Origin正常获取为本地地址
  • 部署至Vercel时,Origin正常获取为Vercel分配的域名

错误返回结果:

{"error":"Access denied. Environment: production. Your Origin: https://localhost:3000 | Whitelist: https://main.xxxxxx.amplifyapp.com"}

相关代码与配置

Middleware校验代码(middleware.ts)

export const middleware = async (req: NextRequest) => {
  const origin = req.nextUrl.origin;

  if (!publicEnv.CORS_WHITELIST?.includes(origin)) {
    return NextResponse.json({ error: `Access denied. Environment: ${process.env.NODE_ENV}. Your Origin: ${origin} | Whitelist: ${publicEnv.CORS_WHITELIST}` }, { status: 405 })
  }
  // ...其他逻辑
}

Amplify配置(amplify.yml)

version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci --cache .npm --prefer-offline
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - .npm/**/*
      - node_modules/**/*

尝试过的配置调整

  1. customHttp.yml:无论是空文件还是添加CORS头配置,问题未解决
    customHeaders:
      - pattern: "**/*"
        headers:
          - key: Access-Control-Allow-Origin
            value: https://main.xxxxxx.amplifyapp.com
          - key: Access-Control-Allow-Headers
            value: Origin, X-Requested-With, Content-Type, Accept, Authorization
          - key: Access-Control-Allow-Methods
            value: GET, POST, PUT, PATCH, DELETE, OPTIONS
    
  2. package.json scripts:尝试两种配置,均无效
    第一种:
    "scripts": {
        "dev": "next dev -p 88888",
        "build": "next build",
        "start": "next start -p 88888",
        "lint": "next lint"
    }
    
    第二种:
    "scripts": {
        "dev": "next dev -p 88888",
        "build": "NODE_ENV=production next build",
        "start": "NODE_ENV=production next start",
        "lint": "next lint"
    }
    

原因分析

AWS Amplify部署NextJS时,默认通过内部反向代理转发请求,req.nextUrl.origin读取的是代理内部的容器端口地址(localhost:3000,对应NextJS在Amplify容器内的运行端口),而非客户端实际请求的外部域名。这是Amplify部署环境与Vercel/本地环境的核心差异点。


解决方案

方案1:从请求头获取真实Origin

放弃使用req.nextUrl.origin,改为读取请求头中的Origin字段(客户端发送的真实来源),同时兼容本地开发场景:

export const middleware = async (req: NextRequest) => {
  // 优先取请求头的真实Origin,本地开发时fallback到nextUrl.origin
  const origin = req.headers.get('origin') || req.nextUrl.origin;

  if (!publicEnv.CORS_WHITELIST?.includes(origin)) {
    return NextResponse.json({ error: `Access denied. Environment: ${process.env.NODE_ENV}. Your Origin: ${origin} | Whitelist: ${publicEnv.CORS_WHITELIST}` }, { status: 405 })
  }
  // ...其他逻辑
}

方案2:通过环境变量强制指定允许的Origin

在AWS Amplify控制台添加环境变量NEXT_PUBLIC_APP_URL,值为你的Amplify应用域名(如https://main.xxxxxx.amplifyapp.com),然后在middleware中直接用该变量作为校验基准:

export const middleware = async (req: NextRequest) => {
  const allowedOrigin = process.env.NODE_ENV === 'production' 
    ? process.env.NEXT_PUBLIC_APP_URL 
    : req.nextUrl.origin;
  const clientOrigin = req.headers.get('origin') || req.nextUrl.origin;

  if (clientOrigin !== allowedOrigin) {
    return NextResponse.json({ error: `Access denied. Environment: ${process.env.NODE_ENV}. Your Origin: ${clientOrigin} | Whitelist: ${allowedOrigin}` }, { status: 405 })
  }
  // ...其他逻辑
}

方案3:调整Amplify代理与NextJS信任配置(进阶)

通过customHttp.yml配置转发真实域名头,同时让NextJS信任Amplify代理:

  1. 修改customHttp.yml:
customHeaders:
  - pattern: "**/*"
    headers:
      - key: X-Forwarded-Proto
        value: https
      - key: X-Forwarded-Host
        value: main.xxxxxx.amplifyapp.com
  1. 修改next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
  async headers() {
    return [
      {
        source: '/api/:path*',
        headers: [
          { key: 'Access-Control-Allow-Credentials', value: 'true' },
          { key: 'Access-Control-Allow-Origin', value: process.env.NEXT_PUBLIC_APP_URL },
          { key: 'Access-Control-Allow-Methods', value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT' },
          { key: 'Access-Control-Allow-Headers', value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' },
        ],
      },
    ]
  },
  // 信任Amplify代理传递的Host头
  trustHostHeader: true,
}

module.exports = nextConfig

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 10:14:55