Node.js配置404页面异常:刷新页面时跳转行为不符合预期
我碰到过一模一样的问题!这本质上是单页应用(SPA)路由和Node.js后端路由的冲突问题,我来给你拆解原因和解决办法:
为什么刷新会跳404?
你现在的代码app.get('*', function(req, res) { res.sendFile(__dirname + '/dashboard/404.html'); });会匹配所有没被其他路由处理的GET请求。这里的核心问题是:
- 首次加载页面时,浏览器请求的是根路径
/,你的前端路由正常加载,显示正确内容; - 但当你刷新某个子页面(比如
/user/profile)时,浏览器会直接向Node.js服务器请求这个路径——而你的后端根本没有配置/user/profile这个路由,所以触发了*通配路由,直接返回了404.html。 - 之前用index.html的时候,刷新返回的是index.html,前端路由会接管这个请求,渲染出对应的子页面,所以看起来正常。
正确的配置方式
根据你的场景,分两种情况处理:
情况1:你在用SPA(比如React/Vue的history模式)
这种情况下,我们需要区分真实的404请求和SPA的路由请求:
const path = require('path'); const express = require('express'); const app = express(); // 1. 先配置静态资源路由(比如css、js、图片等) app.use(express.static(path.join(__dirname, 'dashboard'))); // 2. 配置你的后端API路由(如果有的话) app.get('/api/get-user', (req, res) => { // 处理你的API逻辑 res.json({ name: 'test' }); }); // 3. SPA路由 fallback:所有非API、非静态资源的请求,返回index.html让前端路由处理 app.get('*', (req, res) => { // 判断是否是SPA路由请求:路径里没有后缀(比如.js/.css)且不是API路径 if (!req.path.startsWith('/api') && !req.path.includes('.')) { res.sendFile(path.join(__dirname, 'dashboard/index.html')); } else { // 真实的404请求:返回404.html并设置404状态码 res.status(404).sendFile(path.join(__dirname, 'dashboard/404.html')); } }); app.listen(3000);
情况2:你没用SPA,只是单纯想处理404
如果你的页面都是静态页面,没有前端路由,那只需要让Express先处理静态资源,当静态资源不存在时再返回404.html:
const path = require('path'); const express = require('express'); const app = express(); // 配置静态资源,设置fallthrough: false表示找不到资源时不继续往下走 app.use(express.static(path.join(__dirname, 'dashboard'), { fallthrough: false })); // 当静态资源找不到时,返回404.html app.use((req, res) => { res.status(404).sendFile(path.join(__dirname, 'dashboard/404.html')); }); app.listen(3000);
关键提醒
- 路由顺序很重要:Express是按从上到下的顺序匹配路由的,所以一定要把静态资源、API路由放在最前面,最后再处理通配路由或404。
- 别忘了设置404状态码:返回404页面时,一定要用
res.status(404),这样浏览器和搜索引擎才能正确识别这是404响应。
内容的提问来源于stack exchange,提问作者Amit Sharma




