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

Node.js中路由参数匹配不存在页面时的404页面渲染问题

Express+EJS 404页面渲染失败问题解决

问题根源分析

你遇到的视图查找错误,核心原因通常是以下两种情况之一:

  1. 404处理中间件位置错误:中间件被放在了其他路由之前,或者没有放在所有路由的最后,导致请求还没匹配到正常路由就被拦截,或者正常路由匹配完后没走到404逻辑。
  2. 带参数路由误匹配:比如你定义了类似/:param的路由,它会匹配所有单段路径(包括不存在的/asdkjbasfijbs),此时代码会尝试渲染对应参数名的视图,但该视图不存在,从而抛出查找错误,而不是进入404中间件。

具体解决方案

1. 确保404中间件放在所有路由最后

Express的路由匹配是按顺序执行的,404中间件必须放在所有正常路由、带参数路由之后,只有当所有路由都匹配失败时,才会触发它。

示例正确代码结构:

const express = require('express');
const app = express();

// 设置视图引擎为EJS
app.set('view engine', 'ejs');
app.set('views', './views'); // 确保views路径正确

// 正常路由:首页
app.get('/', (req, res) => {
  res.render('index');
});

// 正常路由:/main
app.get('/main', (req, res) => {
  res.render('main');
});

// 带参数路由(如果有):先验证参数合法性,不合法则交给404处理
app.get('/user/:id', (req, res, next) => {
  // 示例:验证id是否为数字(根据你的业务逻辑调整)
  if (!/^\d+$/.test(req.params.id)) {
    next(); // 跳过当前路由,交给下一个中间件(即404)
    return;
  }
  res.render('user');
});

// 404处理中间件:必须放在所有路由最后
app.use((req, res) => {
  res.status(404).render('404'); // 确保views文件夹下有404.ejs
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

2. 修复带参数路由的误匹配问题

如果你有类似/:page这种会匹配任意单段路径的路由,必须在路由内部做白名单验证,只允许渲染存在的视图:

// 带参数路由:限制允许的页面名称
app.get('/:page', (req, res, next) => {
  // 白名单:列出所有存在的视图文件名
  const allowedPages = ['main', 'about', 'contact'];
  if (allowedPages.includes(req.params.page)) {
    res.render(req.params.page);
  } else {
    next(); // 交给404中间件处理
  }
});

// 404中间件
app.use((req, res) => {
  res.status(404).render('404');
});

3. 检查视图文件路径

确保views文件夹下确实存在404.ejs文件,如果404页面放在子文件夹(比如views/errors/404.ejs),则需要修改渲染路径:

app.use((req, res) => {
  res.status(404).render('errors/404');
});

错误写法对比(避免踩坑)

  • 错误:404中间件放在路由前
// 错误:所有请求都会直接返回404,正常路由无法触发
app.use((req, res) => {
  res.status(404).render('404');
});

app.get('/', (req, res) => {
  res.render('index');
});
  • 错误:带参数路由无验证
// 错误:会匹配任意单段路径,尝试渲染不存在的视图而报错
app.get('/:page', (req, res) => {
  res.render(req.params.page); // 当page不存在时抛出视图查找错误
});

// 404中间件永远不会被触发
app.use((req, res) => {
  res.status(404).render('404');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:05:17