如何配置CORS使React前端与Next.js后端正常通信
解决Next.js API路由的CORS跨域问题
针对你的React(运行在localhost:3001)和Next.js(运行在localhost:3000)跨域场景,我给你几个靠谱的解决方案,按推荐优先级排序:
方案1:用Next.js全局headers配置(最省心,无需额外依赖)
直接在项目根目录的next.config.js里添加CORS相关的headers配置,所有API路由都会自动应用该规则,不用在每个API文件里重复编写:
// next.config.js module.exports = { async headers() { return [ { // 匹配所有API路由路径 source: '/api/:path*', headers: [ { key: 'Access-Control-Allow-Credentials', value: 'true' }, // 生产环境建议替换成你的前端域名,比*更安全 { key: 'Access-Control-Allow-Origin', value: 'http://localhost:3001' }, { 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' }, ], }, ]; }, };
配置完成后重启Next.js服务即可,这个方案会自动处理浏览器的OPTIONS预检请求,无需手动编写额外逻辑。
方案2:正确使用NextCors包(适合细粒度控制场景)
你之前用NextCors没生效,大概率是因为把它放在了req.method的判断分支里,导致GET/PUT之外的请求(比如浏览器自动发送的OPTIONS预检请求)没触发CORS配置。要把NextCors的调用放在所有业务逻辑之前:
// pages/api/employee.js import NextCors from 'nextjs-cors'; import prisma from '../../lib/prisma'; // 替换成你的prisma实例路径 export default async function handler(req, res) { // 第一步:先调用NextCors,放在所有业务逻辑之前 await NextCors(req, res, { methods: ['GET', 'PUT', 'OPTIONS'], origin: 'http://localhost:3001', // 指定具体前端域名更安全 optionsSuccessStatus: 200, }); // 处理业务逻辑 if (req.method === 'PUT') { // 注意:你之前写的req.employee应该是req.body才对 const feed = await prisma.employee.create({ data: req.body, }); res.status(200).json(feed); } else if (req.method === 'GET') { const feed = await prisma.employee.findMany({}); res.status(200).json(feed); } else { res.status(404).end(); } }
方案3:手动配置CORS(适合理解底层逻辑)
如果不想用第三方包,手动配置时必须处理OPTIONS预检请求——浏览器会在跨域的PUT/POST等请求前先发OPTIONS请求验证权限,之前你手动加头没生效就是因为忽略了这一步:
// pages/api/employee.js import prisma from '../../lib/prisma'; export default async function handler(req, res) { // 优先处理OPTIONS预检请求 if (req.method === 'OPTIONS') { res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3001'); res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); return res.status(200).end(); } // 为其他请求设置CORS头 res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3001'); // 处理业务逻辑 if (req.method === 'PUT') { const feed = await prisma.employee.create({ data: req.body, }); res.status(200).json(feed); } else if (req.method === 'GET') { const feed = await prisma.employee.findMany({}); res.status(200).json(feed); } else { res.status(404).end(); } }
额外提示:
- 生产环境不要用
*作为Access-Control-Allow-Origin,指定具体的前端域名能提升安全性 - 可以在前端打印
process.env.REACT_APP_API_URL确认是否正确设置为http://localhost:3000
内容的提问来源于stack exchange,提问作者timmmmmb
相关产品推荐
相关产品推荐

