Vercel根路由(/)返回服务器源代码问题排查求助
环境与配置
目录结构
+ myapp_root_dir |-+ api | |-+ public | | |-- index.html | | |-- layout.css | | |-- main.js | |-- index.js |-- vercel.json
Express服务器代码(api/index.js)
import express from 'express' // 注:原代码中"form"为拼写错误,应为"from" import session from 'express-session'; import cors from 'cors' import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express() app.use(session({ secret: 'somesecrethere', resave: true, saveUninitialized: true, cookie: { secure: false, } })) app.use(cors()) app.use(express.json()) app.use(express.urlencoded()) app.use(express.static("public", { index: false })) app.get("/", (req, res) => { res.sendFile(__dirname + "/public/index.html") }) app.get("/time", (req, res) => { res.send(new Date().getTime().toString()) }) export default app
初始vercel.json配置
{ "rewrites": [ { "source": "/time", "destination": "/api" }, { "source": "/", "destination": "/api" } ] }
问题现象
/time端点正常返回当前时间戳- 访问根路径
/时,直接返回api/index.js的源代码,而非预期的public/index.html
临时解决方法
将根路径的处理逻辑移至新路由/home,并修改vercel.json添加重定向规则:
{ "rewrites": [ { "source": "/time", "destination": "/api" }, { "source": "/home", "destination": "/api" } ], "redirects": [ { "source": "/", "destination": "/home" } ] }
此方法可临时解决问题,但疑惑点在于:另一使用完全相同vercel.json配置的应用运行正常,需明确问题根源。
问题根源分析
Vercel根路径的特殊解析逻辑
Vercel对无服务器函数的根路径请求(即重写后的/指向/api)存在特殊处理:当直接将根路径重写指向/api时,Vercel可能绕过Express的路由系统,直接读取并返回api/index.js的源代码,而非将请求转发给Express应用处理。而子路径(如/time)的重写则会正常转发到Express路由。静态文件目录位置的影响
你的静态文件目录public放在api文件夹下,而Vercel默认优先读取项目根目录下的静态资源。当根路径请求过来时,Vercel找不到根目录的静态文件,就会直接处理无服务器函数的根路径请求,从而触发上述问题。另一个正常运行的应用,大概率是将public目录放在了项目根目录,或者其路由处理逻辑避免了Vercel的特殊解析行为。代码拼写错误的潜在影响
原代码中import express form 'express'的form是拼写错误,应为from——虽然你提到/time端点正常,说明实际代码可能已修正,但如果未修正,会导致Express初始化失败,进一步触发Vercel返回函数文件内容的 fallback 逻辑。
正确的解决方式
方式1:调整vercel.json重写规则
修改重写规则,让所有请求都转发到API,避免单独指定根路径:
{ "rewrites": [ { "source": "/(.*)", "destination": "/api" } ] }
这样Vercel会将所有请求转发到Express应用,由Express的路由统一处理根路径和/time端点。
方式2:调整静态文件目录位置
将public目录移到项目根目录:
+ myapp_root_dir |-+ api | |-- index.js |-+ public | |-- index.html | |-- layout.css | |-- main.js |-- vercel.json
然后修改Express代码中的路径配置:
// 修正静态文件路径 app.use(express.static(path.join(__dirname, "../public"), { index: false })) // 修正根路径的sendFile路径 app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "../public/index.html")) })
这种方式符合Vercel的静态资源优先处理逻辑,根路径请求会先检查public/index.html,再转发到API。
方式3:启用Express静态文件的索引页
如果保留public在api目录下,可移除express.static的index: false配置,让Express自动返回public/index.html作为根路径响应:
app.use(express.static("public"))
同时删除根路径的app.get("/")路由,由静态文件中间件自动处理。
内容的提问来源于stack exchange,提问作者Wais Kamal

