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

Next.js API路由与中央中间件的CORS问题排查求助

解决Next.js API路由的CORS问题

核心问题分析

你当前的中间件只处理了OPTIONS预飞请求,但实际的业务请求(GET/POST)返回的响应中并没有添加CORS头。浏览器会同时校验预飞请求和实际请求的响应头,只要实际请求缺少Access-Control-Allow-Origin,就会触发CORS拦截。

修复后的中间件配置

修改middleware.ts,确保对允许的来源,无论是预飞请求还是实际业务请求,都添加正确的CORS头:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

const allowedOrigins = [
    'http://localhost:8888',
    'https://example.com',
    'https://another-example.com',
];

export function middleware(request: NextRequest) {
    const origin = request.headers.get('Origin');
    const isAllowedOrigin = origin && allowedOrigins.includes(origin);

    // 处理OPTIONS预飞请求
    if (request.method === 'OPTIONS') {
        if (!isAllowedOrigin) {
            return new Response(null, { status: 403 });
        }
        const responseHeaders = new Headers()
        responseHeaders.append('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        responseHeaders.append('Access-Control-Allow-Headers', 'Content-Type, Authorization')
        responseHeaders.append('Access-Control-Allow-Credentials', 'true')
        responseHeaders.append('Access-Control-Allow-Origin', origin!)
        return new Response(null, { status: 200, headers: responseHeaders })
    }

    // 为实际业务请求添加CORS响应头
    const response = NextResponse.next();
    if (isAllowedOrigin) {
        response.headers.append('Access-Control-Allow-Origin', origin!);
        response.headers.append('Access-Control-Allow-Credentials', 'true');
    }
    return response;
}

// 限制中间件仅作用于API路由(提升性能,可选)
export const config = {
    matcher: '/api/:path*',
};

额外排查要点

  1. 严格匹配Origin:浏览器发送的Origin头可能和你配置的存在细微差异(比如末尾斜杠、大小写),可以在middleware中添加console.log(origin)查看实际值,确保和allowedOrigins中的条目完全一致。
  2. 避免路由内重复设置头:检查你的pages/api/me.ts中是否手动设置了Access-Control-Allow-Origin,如果有会和中间件的配置冲突,需要移除。
  3. 清除浏览器缓存:浏览器会缓存预飞请求结果,修改配置后建议清空缓存或使用无痕模式测试。
  4. 验证响应头:用curl命令测试响应头是否正确返回:
    # 测试预飞请求
    curl -X OPTIONS http://localhost:3000/api/me -H "Origin: http://localhost:8888" -v
    # 测试实际请求
    curl http://localhost:3000/api/me -H "Origin: http://localhost:8888" -v
    
    确认响应中包含Access-Control-Allow-Origin: http://localhost:8888。

内容的提问来源于stack exchange,提问作者János

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:45:12