部署Next.js 13到Vercel时与MongoDB API交互的CORS问题求助
解决Next.js 13部署到Vercel时的CORS问题
1. 修正Fetch请求的端点地址
你当前的fetch用了http://localhost:3000,这是本地开发环境专属地址,部署到Vercel后完全不可用:
- 前端在Vercel域名下时,请求
localhost会指向用户本地机器,而非你的Vercel服务器 - 即使是服务器端组件的fetch,用localhost也会引发跨域问题(Vercel服务器环境中localhost并非你的API地址)
正确做法是使用相对路径,去掉域名部分:
// 单个资源的PUT/DELETE/GET请求 const res = await fetch(`/api/topics/${id}`, { cache: 'no-store', }); // 通用的GET/POST请求 const res = await fetch(`/api/topics/`, { cache: 'no-store', });
这种写法会自动适配本地和部署环境的域名,同域下完全不会触发CORS问题。
2. 修正next.config.js的CORS配置错误
你的配置存在两个核心问题:
Access-Control-Allow-Origin值错误:该字段应填写请求来源的域名(比如本地是http://localhost:3000,部署后是你的Vercel域名),而非API路径。如果允许所有域名(不推荐生产环境)可设为*,但搭配Access-Control-Allow-Credentials: true时不能用*,必须指定具体域名。- 同域请求无需配置CORS头:前端和API路由属于同一域名时,浏览器不会触发CORS预检,配置这些头反而可能引发冲突。
如果你的API需要被外部域名调用,正确配置示例(生产环境建议指定具体域名):
/** @type {import('next').NextConfig} */ const nextConfig = { async headers() { return [ { source: '/api/:path*', headers: [ { key: 'Access-Control-Allow-Credentials', value: 'true' }, // 生产环境替换为你的Vercel域名 { key: 'Access-Control-Allow-Origin', value: process.env.NODE_ENV === 'production' ? 'https://your-vercel-domain.vercel.app' : 'http://localhost:3000' }, { key: 'Access-Control-Allow-Methods', value: 'GET, DELETE, PATCH, 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' }, ], }, ]; }, }; module.exports = nextConfig;
如果仅做同域调用,直接删除这部分CORS配置即可。
3. 确认API路由结构正确性
你的项目文件夹结构完全符合Next.js 13 App Router规范:
/app/api/topics/route.ts:处理/api/topics的GET/POST请求/app/api/topics/[id]/route.ts:处理/api/topics/${id}的GET/PUT/DELETE请求
Vercel会自动识别这些路由,部署后可正常访问,无需修改。
4. 额外检查:处理OPTIONS预检请求
如果API需要接收外部域名的复杂请求(比如带自定义头、PUT/DELETE方法),需在API路由中手动处理OPTIONS请求。以/app/api/topics/route.ts为例:
import { NextResponse } from 'next/server'; export async function OPTIONS() { return NextResponse.json({}, { headers: { 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': process.env.NODE_ENV === 'production' ? 'https://your-vercel-domain.vercel.app' : 'http://localhost:3000', 'Access-Control-Allow-Methods': 'GET, DELETE, PATCH, POST, PUT', 'Access-Control-Allow-Headers': 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version', }, }); } // 你的GET/POST处理函数 export async function GET() { /* ... */ } export async function POST() { /* ... */ }
确保预检请求被正确响应,避免CORS错误。
内容的提问来源于stack exchange,提问作者Carlos Damian Perez
相关产品推荐
相关产品推荐

