You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vercel根路由(/)返回服务器源代码问题排查求助

问题:Vercel部署Express无服务器API后,根路径返回服务器代码而非HTML

环境与配置

目录结构

+ 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配置的应用运行正常,需明确问题根源。


问题根源分析

  1. Vercel根路径的特殊解析逻辑
    Vercel对无服务器函数的根路径请求(即重写后的/指向/api)存在特殊处理:当直接将根路径重写指向/api时,Vercel可能绕过Express的路由系统,直接读取并返回api/index.js的源代码,而非将请求转发给Express应用处理。而子路径(如/time)的重写则会正常转发到Express路由。

  2. 静态文件目录位置的影响
    你的静态文件目录public放在api文件夹下,而Vercel默认优先读取项目根目录下的静态资源。当根路径请求过来时,Vercel找不到根目录的静态文件,就会直接处理无服务器函数的根路径请求,从而触发上述问题。另一个正常运行的应用,大概率是将public目录放在了项目根目录,或者其路由处理逻辑避免了Vercel的特殊解析行为。

  3. 代码拼写错误的潜在影响
    原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 11:01:23