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)
解决方案
问题根源
- 中间件顺序错误:Express按代码顺序执行中间件和路由,你把404捕获的中间件放在了自定义GET路由前面,导致请求还没到达根路由和/react路由就被404拦截。
- 路径错误:
__dirname指向server文件夹,而client和server是根目录下的同级文件夹,所以访问client的路径应该用../client/public而非client/public,否则会在server文件夹下找client,导致路径不存在。 - 静态文件中间件与路由冲突:同时设置静态文件中间件和GET路由返回文件,可能导致优先级问题。
修改步骤
- 调整路由顺序:把自定义的
app.get("/")和app.get("/react")移到404捕获中间件之前。 - 修正路径:所有指向client的路径都改为
path.join(__dirname, '../client/public')。 - 优化静态文件配置:保留必要的静态文件中间件,避免重复逻辑。
修改后的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
相关产品推荐
相关产品推荐

