Vercel部署Express服务访问报404 not found问题排查求助
Express部署Vercel访问报404问题修复
问题现象
尝试将Express服务部署到Vercel解决前端CORS问题,部署后访问线上地址返回404 page not found错误,相同代码本地localhost运行完全正常。
故障相关原配置如下:
// vercel.json { "version": 2, "builds": [ { "src": "./index.js", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "/" } ], "rewrites": [{ "source": "/api/(.*)", "destination": "/api" }] } //index.js const express = require("express"); const cors = require("cors"); const axios = require("axios"); const app = express(); const PORT = process.env.PORT || 3000; require("dotenv").config(); let corsOptions = { origin: ["http://localhost:3000", "https://humanscape-team5a.netlify.app"], }; app.use(cors(corsOptions)); app.get("/", (req, res) => { const textQuery = req.query.searchText; const numOfRowsQuery = req.query.numOfRows; axios .get( "http://apis.data.go.kr/B551182/diseaseInfoService/getDissNameCodeList", { params: { sickType: 1, medTp: 2, diseaseType: "SICK_NM", searchText: textQuery, ServiceKey: process.env.KEY, numOfRows: numOfRowsQuery, _type: "json", }, } ) .then(response => res.send(response.data)); }); app.listen(PORT, () => { console.log(`Server running on ${PORT}`); });
故障原因
本地运行正常是因为本地启动了常驻Node进程监听3000端口,和Vercel的Serverless运行环境逻辑完全不同,配置存在4个核心错误:
vercel.json中routes规则的dest值为"/",没有指向实际的服务入口文件,所有请求转发到空路径直接触发404- 多余的
rewrites规则指向不存在的/api路径,没有实际作用 - 代码中写了
app.listen逻辑,Vercel Serverless环境不需要手动启动端口监听,该逻辑不会正常生效,同时没有导出Express实例供Vercel运行时调用 - 接口直接挂载在根路径
/,容易和Vercel默认的静态资源路由规则冲突
修复方案
- 调整项目目录结构,在根目录新建
api文件夹,将原根目录下的index.js移动到api目录下,Vercel会自动识别该目录下的文件为Serverless函数,无需额外配置构建规则。 - 替换根目录下
vercel.json的全部内容为以下配置:
{ "version": 2, "rewrites": [ { "source": "/(.*)", "destination": "/api/index.js" } ] }
- 修改
api/index.js代码,删除app.listen相关逻辑,最后导出Express实例,同时建议将接口路径从根路径调整为/api避免路由冲突,修改后代码如下:
const express = require("express"); const cors = require("cors"); const axios = require("axios"); require("dotenv").config(); const app = express(); const corsOptions = { origin: ["http://localhost:3000", "https://humanscape-team5a.netlify.app"], credentials: true }; app.use(cors(corsOptions)); // 接口路径调整为/api,避免和根路径静态规则冲突 app.get("/api", (req, res) => { const { searchText: textQuery, numOfRows: numOfRowsQuery } = req.query; axios .get( "http://apis.data.go.kr/B551182/diseaseInfoService/getDissNameCodeList", { params: { sickType: 1, medTp: 2, diseaseType: "SICK_NM", searchText: textQuery, ServiceKey: process.env.KEY, numOfRows: numOfRowsQuery, _type: "json", }, } ) .then(response => res.send(response.data)) .catch(err => res.status(500).send({ code: 500, msg: "接口请求异常" })); }); // 导出实例供Vercel运行时调用,不要保留app.listen逻辑 module.exports = app;
- 登录Vercel项目后台,进入
Settings - Environment Variables页面,添加本地.env中存储的KEY环境变量,Vercel不会自动读取本地未上传的.env文件。
验证方式
重新触发项目部署后,访问https://你的Vercel分配域名/api?searchText=测试关键词&numOfRows=10即可正常返回接口数据,前端将请求地址替换为该路径即可正常解决CORS问题,不会再出现404错误。
内容的提问来源于stack exchange,提问作者easeurmind
相关产品推荐
相关产品推荐

