Nest.js部署Vercel后POST请求遇CORS错误求助
问题分析与解决方案
核心问题
部署到Vercel的Nest.js服务,POST请求触发CORS错误(预飞请求OPTIONS未返回Access-Control-Allow-Origin头),但GET请求和Postman测试正常。这说明浏览器的跨域预飞请求未被正确转发到Nest.js服务处理,或是Vercel配置拦截了OPTIONS请求。
具体解决方案
1. 修正Vercel路由配置,添加OPTIONS请求支持
你的vercel.json中routes的methods数组缺少OPTIONS方法,导致Vercel不会将预飞请求转发到Nest.js服务,而是自行处理但未添加CORS头。修改如下:
{ "version": 2, "name": "next-store-server", "buildCommand": "npm run build", "installCommand": "npm install", "builds": [ { "src": "dist/main.js", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "dist/main.js", "methods": ["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"] } ] }
2. 修正Vercel的build命令
当前buildCommand设为npm start是错误的,npm start是启动服务命令,而Vercel的build阶段需要编译Nest.js项目到dist目录,应改为:
"buildCommand": "npm run build"
同时确保package.json中存在对应编译脚本:
{ "scripts": { "build": "nest build", "start": "node dist/main.js" } }
3. 优化Nest.js的CORS配置(可选但更健壮)
硬编码origin可能因域名变动失效,改为动态判断origin,同时确保配置顺序正确(在app.listen()前调用):
async function bootstrap() { const app = await NestFactory.create(AppModule); // 放在所有路由注册之前 app.enableCors({ origin: (origin, callback) => { const allowedOrigins = ['http://localhost:3000', 'https://next-store-liard-three.vercel.app']; // 允许无origin的请求(比如Postman) if (!origin || allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, allowedHeaders: ['Accept', 'Content-Type'], methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'], preflightContinue: false, optionsSuccessStatus: 204, credentials: true, }); app.setGlobalPrefix('api'); await app.listen(process.env.PORT || 3000); } bootstrap();
4. 确保Axios携带Credentials
因为你配置了credentials: true,需要让Axios请求时携带凭证:
import axios from "axios"; import { FAuth, IUser } from "./Auth.types"; const axiosInstance = axios.create({ withCredentials: true, }); const AuthService = { async registration(dto: IUser) { const { data } = await axiosInstance.post<FAuth>( `${process.env.NEXT_PUBLIC_SERVER_API_URL}/api/auth/registration`, dto, ); return data; }, async login(dto: IUser) { const { data } = await axiosInstance.post<FAuth>(`${process.env.NEXT_PUBLIC_SERVER_API_URL}/api/auth/login`, dto); return data; }, };
验证步骤
- 重新部署Vercel服务,确保配置生效
- 清除浏览器缓存,重新发起POST请求
- 查看浏览器Network面板的OPTIONS请求,确认响应头包含
Access-Control-Allow-Origin
内容的提问来源于stack exchange,提问作者Oleksandr
相关产品推荐
相关产品推荐

