Vercel部署应用遭遇CORS错误,已配置相关项仍未解决求排查
开发环境运行正常,但部署到Vercel后出现以下错误:
about:1 Access to XMLHttpRequest at 'https://portfolio-beryl-eight-48.vercel.app/api/github/fetch-profile' from origin 'https://ckolaportfolio.vercel.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
现有配置代码
Express后端代码
const config = require('./utils/config') const express = require('express') const app = express() const cors = require('cors') const middleware = require('./utils/middleware') const githubRouter = require('./controllers/github') app.use(cors()); app.use(express.static('dist')) app.use(express.json()) app.use(middleware.requestLogger) app.use('/api/github', githubRouter) app.use(middleware.unknownEndpoint) app.use(middleware.errorHandler) module.exports = app
vercel.json配置
{ "version": 2, "builds": [ { "src": "index.js", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "index.js" } ], "headers": [ { "source": "/api/(.*)", "headers": [ { "key": "Access-Control-Allow-Origin", "value": "https://ckolaportfolio.vercel.app" }, { "key": "Access-Control-Allow-Methods", "value": "GET, POST, OPTIONS" }, { "key": "Access-Control-Allow-Headers", "value": "Content-Type, Authorization" } ] } ] }
config.js环境变量配置
require('dotenv').config() const PORT = process.env.PORT const GITHUB_TOKEN = process.env.GITHUB_TOKEN const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS.split(',').map(origin => origin.trim()) const NODE_ENV = process.env.NODE_ENV || 'development' const FRONTEND_URL = process.env.FRONTEND_URL || 'https://ckolaportfolio.vercel.app' module.exports = { PORT, GITHUB_TOKEN, ALLOWED_ORIGINS, NODE_ENV, FRONTEND_URL }
请求头及响应头截图:
可能的解决方向
显式配置CORS允许的源
当前app.use(cors())默认允许所有源,既没用到config里定义的ALLOWED_ORIGINS,还可能和Vercel的headers配置冲突。改成显式指定允许的源:app.use(cors({ origin: config.ALLOWED_ORIGINS, credentials: true, methods: ['GET', 'POST', 'OPTIONS'] }));同时确认Vercel环境变量
ALLOWED_ORIGINS的值是https://ckolaportfolio.vercel.app,不要带多余空格。调整Vercel路由匹配顺序
当前routes里"/(.*)"会匹配所有请求,导致headers中针对/api/(.*)的规则被覆盖。调整顺序让API路由优先匹配:"routes": [ { "src": "/api/(.*)", "dest": "index.js" }, { "src": "/(.*)", "dest": "index.js" } ]部署时勾选"Override Build Cache",避免旧配置缓存导致新设置不生效。
确保CORS中间件优先级最高
预检请求(OPTIONS)需要被CORS中间件优先处理,如果unknownEndpoint或errorHandler在CORS之前拦截请求,会导致预检失败。把app.use(cors())放在所有中间件和路由的最前面。验证环境变量是否正确加载
进入Vercel项目的Settings → Environment Variables,确认ALLOWED_ORIGINS、FRONTEND_URL等变量已正确设置,并且部署时选择了对应环境。可以在代码里加日志console.log('Allowed origins:', config.ALLOWED_ORIGINS),部署后查看Vercel日志确认变量值。排查静态文件冲突
启用的express.static('dist')如果存在和API路由同名的文件/目录,Vercel会优先返回静态文件而非API响应。检查dist目录,确保没有api相关的内容。
内容的提问来源于stack exchange,提问作者ChrisKola99

