Angular与NodeJS后端(Vercel部署)的CORS问题求助
解决Vercel部署的NodeJS TypeScript后端与Angular的CORS问题
1. 配置Vercel的vercel.json
Vercel会通过该文件设置全局响应头,是解决跨域的核心步骤。确保配置匹配你的API路由并允许目标Angular域名:
{ "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Access-Control-Allow-Credentials", "value": "true" }, { "key": "Access-Control-Allow-Origin", "value": "https://your-angular-app.vercel.app" }, { "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" } ] } ] }
- 若需允许多个域名,不能直接用逗号分隔,需在后端代码中动态判断
Origin请求头并返回对应值。 - 提交该文件到Git后重新部署Vercel后端,确保配置生效。
2. NodeJS后端代码添加CORS处理
即使Vercel配置了全局头,仍需在后端框架中处理预检请求(OPTIONS),以兼容所有场景。
方式一:使用cors包(推荐)
安装依赖:
npm install cors
在TypeScript代码中配置:
import express from 'express'; import cors from 'cors'; const app = express(); // 动态配置允许的域名 const corsOptions = { origin: (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => { const allowedOrigins = ['https://your-angular-app.vercel.app', 'http://localhost:4200']; if (!origin || allowedOrigins.includes(origin)) { callback(null, true); } else { callback(new Error('Not allowed by CORS')); } }, credentials: true }; // 全局应用CORS配置 app.use(cors(corsOptions)); // 显式处理OPTIONS预检请求 app.options('*', cors(corsOptions)); // 示例API路由 app.get('/api/data', (req, res) => { res.json({ data: 'Sample data from backend' }); }); export default app;
方式二:手动处理CORS(无依赖)
import express from 'express'; const app = express(); app.use((req, res, next) => { const allowedOrigins = ['https://your-angular-app.vercel.app', 'http://localhost:4200']; const origin = req.headers.origin; if (origin && allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin); } res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.setHeader('Access-Control-Allow-Credentials', 'true'); // 处理预检请求,直接返回200 if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); // 示例API路由 app.get('/api/data', (req, res) => { res.json({ data: 'Sample data from backend' }); }); export default app;
3. Angular本地开发的代理配置
如果Angular在本地http://localhost:4200运行,可通过代理转发请求避免跨域:
- 在Angular项目根目录创建
proxy.conf.json:
{ "/api": { "target": "https://your-nodejs-backend.vercel.app", "secure": true, "changeOrigin": true } }
- 修改
angular.json中的serve配置,添加代理引用:
"architect": { "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "your-angular-app:build", "proxyConfig": "proxy.conf.json" } } }
- 重启Angular开发服务器,此时请求
/api/data会自动转发到Vercel后端。
4. 验证与排错
- 用curl测试后端CORS配置:
curl -H "Origin: https://your-angular-app.vercel.app" -I https://your-nodejs-backend.vercel.app/api/data
检查响应头是否包含正确的Access-Control-Allow-Origin值。
- 查看浏览器控制台的具体错误信息,区分是Origin不允许、Headers不支持还是预检请求失败。
内容的提问来源于stack exchange,提问作者Mark Baumann
相关产品推荐
相关产品推荐

