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

Express根路由无法渲染main.html页面问题求助

问题:Express根路由返回404错误,无法渲染server端main.html

我将Express后端与React前端分置于独立文件夹,目录结构为根目录下包含client(内有public/index.html)和server(内有public/main.html、app.js)。期望根路由(/)渲染server端的main.html,/react路由渲染客户端的index.html,/users路由可正常工作,但根路由始终返回404错误。已注释原index.js路由代码,调整路径后仍无法解决问题。

目录结构

根目录
├── client
│   └── public
│       └── index.html
└── server
    ├── public
    │   └── main.html
    └── app.js

服务器端app.js代码

var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");

var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");

var app = express();
const port = process.env.PORT || 4000;
app.listen(port);

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");

app.use(logger("dev"));
app.use(express.json());
var cors = require("cors");
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use("/", express.static(path.join(__dirname, "public")));
app.use("/react", express.static(path.join(__dirname, "client/public")));

app.use("/users", usersRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});
app.get("/", function (req, res) {
  res.sendFile(path.join(__dirname, "public/main.html"));
});
app.get("/react", function (req, res) {
  res.sendFile(path.join(__dirname, "client/public/index.html"));
});
module.exports = app;

Server端main.html代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="stylesheets/style.css" />

    <title>Home</title>
    
  </head>
  <body>
    <h1 class="red">This is Home</h1>
    
  </body>
</html>

注释后的index.js代码

// var express = require("express");
// var router = express.Router();

// router.get("/", function (req, res, next) {
//   res.json([
//     {
//       id: 1,
//       username: "samsepi0l",
//     },
//     {
//       id: 2,
//       username: "D0loresH4ze",
//     },
//   ]);
// });

// module.exports = router;

错误页面信息

Not Found
404
NotFoundError: Not Found
    at /Users/home/self/backtest/server/app.js:31:8
    at Layer.handle [as handle_request] (/Users/home/self/backtest/server/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/home/self/backtest/server/node_modules/express/lib/router/index.js:317:13)
    at /Users/home/self/backtest/server/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/home/self/backtest/server/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/home/self/backtest/server/node_modules/express/lib/router/index.js:275:10)
    at SendStream.error (/Users/home/self/backtest/server/node_modules/serve-static/index.js:121:7)
    at SendStream.emit (node:events:513:28)
    at SendStream.error (/Users/home/self/backtest/server/node_modules/send/index.js:270:17)
    at SendStream.onStatError (/Users/home/self/backtest/server/node_modules/send/index.js:421:12)

解决方案

问题根源

  1. 中间件顺序错误:Express按代码顺序执行中间件和路由,你把404捕获的中间件放在了自定义GET路由前面,导致请求还没到达根路由和/react路由就被404拦截。
  2. 路径错误:__dirname指向server文件夹,而client和server是根目录下的同级文件夹,所以访问client的路径应该用../client/public而非client/public,否则会在server文件夹下找client,导致路径不存在。
  3. 静态文件中间件与路由冲突:同时设置静态文件中间件和GET路由返回文件,可能导致优先级问题。

修改步骤

  1. 调整路由顺序:把自定义的app.get("/")和app.get("/react")移到404捕获中间件之前。
  2. 修正路径:所有指向client的路径都改为path.join(__dirname, '../client/public')。
  3. 优化静态文件配置:保留必要的静态文件中间件,避免重复逻辑。

修改后的app.js代码

var createError = require("http-errors");
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");

var usersRouter = require("./routes/users");

var app = express();
const port = process.env.PORT || 4000;
app.listen(port);

// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");

app.use(logger("dev"));
app.use(express.json());
var cors = require("cors");
app.use(cors());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());

// 配置静态文件:server的public目录
app.use("/", express.static(path.join(__dirname, "public")));
// 配置react的静态文件目录
app.use("/react", express.static(path.join(__dirname, "../client/public")));

// 挂载users路由
app.use("/users", usersRouter);

// 自定义路由:根路由返回main.html
app.get("/", function (req, res) {
  res.sendFile(path.join(__dirname, "public/main.html"));
});
// /react路由返回client的index.html
app.get("/react", function (req, res) {
  res.sendFile(path.join(__dirname, "../client/public/index.html"));
});

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get("env") === "development" ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render("error");
});

module.exports = app;

额外说明

  • 如果stylesheets/style.css存在于server/public目录下,静态文件配置会自动处理该资源的访问,无需额外路由。
  • 若React项目是通过create-react-app创建的,建议在生产环境将build后的文件作为静态资源挂载,而非直接用public目录。

内容的提问来源于stack exchange,提问作者NS H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 08:23:12