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

Express.js路由失效 Jade/Pug渲染title报错问题排查

问题根因
  • 路由与中间件顺序完全错误。Express按代码书写顺序从上到下匹配请求,你把app.listen、单页路由、通配符路由全部写在了基础中间件、挂载路由的前面,请求到达后会先命中提前写的app.get('*')通配逻辑,触发后续404错误流程,根本到不了后续挂载的/、/contact路由。
  • 父模板layout.jade存在未定义的title变量引用。你只删除了子页面模板中的title插值,没有修改被继承的layout模板,所有继承layout的页面(index、contact、error页)渲染时都会尝试读取title变量,变量不存在就会抛错。guardian路由能正常运行,是因为它写了完整的HTML结构,没有继承layout,不会触发这个错误。
  • 路由重复定义。你既在app.js中直接通过app.get写了/、/contact的处理逻辑,又后续通过app.use挂载了对应路径的router,同一路径绑定多个处理函数会产生逻辑冲突。
  • 视图路径配置不规范。你用相对路径./views配置视图目录,启动目录变化时会出现找不到模板的问题。
  • 模板语法错误。index.jade中h1= WELCOME!写法有误,等号后会被识别为变量名,WELCOME未定义会直接抛错。
  • router文件存在冗余代码。routes/index.js中多余创建了express实例,无实际作用还可能引发未知问题。
修复方案
  1. 重构app.js代码顺序,严格遵循「依赖引入 → 实例创建 → 视图配置 → 基础中间件注册 → 路由挂载 → 404处理 → 全局错误处理 → 端口监听」的顺序编写,核心修正后的代码如下:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const port = 5000;

// 引入路由模块
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var contactRouter = require('./routes/contact');
var mealRouter = require('./routes/meal');
var gadginRouter = require('./routes/gadgin');
var aboutRouter = require('./routes/about');

var app = express();

// 视图引擎配置
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// 基础中间件 必须放在路由之前注册
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 挂载路由
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/about', aboutRouter);
app.use('/contact', contactRouter);
app.use('/gadgin', gadginRouter);
app.use('/meal', mealRouter);

// 独立guardian路由
app.get('/member/:name/planet/:home', (req, res) => {
    const memberDetails = {
        member: req.params.name,
        planet: req.params.home,
        title: 'Guardian Page'
    }
    res.render('guardian', memberDetails);
});

// 404捕获 放在所有路由之后
app.use(function(req, res, next) {
    next(createError(404));
});

// 全局错误处理 放在所有中间件最后
app.use(function(err, req, res, next) {
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
    res.status(err.status || 500);
    res.render('error', {title: '错误页'});
});

// 端口监听 放在代码最末尾
app.listen(port, () => {
    console.log(`Server started at port ${port}`);
});

module.exports = app;
  1. 修复模板title变量问题,两种方案二选一即可
    • 方案一:打开layout.jade,找到title= title的写法,改成固定硬编码值,比如title Gadfit站点,不需要动态传值。
    • 方案二:在所有调用res.render的位置,第二个参数传入title字段,比如contact路由中写res.render('contact', {title: '联系我们'}),index路由中写res.render('index', {title: '首页'}),保证模板能读取到title变量。
  2. 修正模板语法:把index.jade里的h1= WELCOME!改成h1 WELCOME!,直接输出固定文本不需要加等号。
  3. 删除冗余代码:
    • 删掉app.js中提前写的app.get('/')、app.get('/contact')、app.get('*')这几段重复路由逻辑,相关处理已经在引入的router文件中实现。
    • 删掉routes/index.js中var app = express();这行冗余代码,路由文件只需要导出router对象即可,不需要重复创建express实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:03:18