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*', };
额外排查要点
- 严格匹配Origin:浏览器发送的
Origin头可能和你配置的存在细微差异(比如末尾斜杠、大小写),可以在middleware中添加console.log(origin)查看实际值,确保和allowedOrigins中的条目完全一致。 - 避免路由内重复设置头:检查你的
pages/api/me.ts中是否手动设置了Access-Control-Allow-Origin,如果有会和中间件的配置冲突,需要移除。 - 清除浏览器缓存:浏览器会缓存预飞请求结果,修改配置后建议清空缓存或使用无痕模式测试。
- 验证响应头:用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" -vAccess-Control-Allow-Origin: http://localhost:8888。
内容的提问来源于stack exchange,提问作者János
相关产品推荐
相关产品推荐

