向Pug模板传递用户数据时遇TypeError: req.next不是函数问题求助
问题分析与解决方案
错误根源
你遇到的TypeError: req.next is not a function是因为中间件isLoggedIn中多次调用next(),且异步操作与同步逻辑的执行顺序混乱,导致Express请求生命周期被破坏,req对象的next方法失效。具体问题点:
- 外层
if (req.cookies.jwt)块末尾,会在异步数据库查询完成前执行next(),之后异步回调里又再次调用next(),同一个请求多次推进生命周期。 - 数据库查询结果判断错误:
result == 0不严谨,mysql查询返回的是数组,应该用result.length === 0。 - 用户赋值错误:
result是查询结果数组,直接取result.id会得到undefined,需用result[0].id。
修正后的代码
1. 修复isLoggedIn中间件
将回调式数据库操作改为Promise形式,确保next()只在合适时机调用一次:
const { promisify } = require('util'); // 先将数据库方法转为Promise格式,避免回调嵌套 const getConnection = promisify(db.getConnection).bind(db); exports.isLoggedIn = async (req, res, next) => { if (req.cookies.jwt) { try { // 验证JWT const decoded = await promisify(jwt.verify)( req.cookies.jwt, process.env.JWT_SECRET ); // 获取数据库连接并查询用户 const connection = await getConnection(); const sqlSearch = "SELECT * FROM users WHERE id = ?"; const search_query = mysql.format(sqlSearch, [decoded.id]); // 手动promisify query方法 const query = promisify(connection.query).bind(connection); const result = await query(search_query); connection.release(); if (result.length === 0) { return next(); } // 用户存在,赋值给req和模板变量 req.user = result[0].id; res.locals.user = result[0].id; return next(); } catch (err) { // JWT验证失败或数据库错误,直接推进流程 return next(); } } // 无JWT时推进流程 next(); };
2. 优化getCourses控制器(可选)
查询不到课程时,渲染404模板而非返回JSON,保持前后端逻辑一致:
exports.getCourses = async (req, res, next) => { try { const connection = await getConnection(); const sqlSearch = "Select * from courses"; const search_query = mysql.format(sqlSearch); const query = promisify(connection.query).bind(connection); const result = await query(search_query); connection.release(); if (result.length === 0) { return res.status(404).render("404", { title: "暂无课程" }); } res.status(200).render("courses", { title: "Courses we offer", courses: result, }); } catch (err) { next(err); // 将错误传递给Express内置错误处理中间件 } };
关键注意事项
- 禁止在异步回调中重复调用
next(),确保每个请求仅调用一次next()。 - 使用
async-await替代嵌套回调,避免回调地狱导致的流程混乱。 - 数据库操作完成后必须释放连接,防止连接池耗尽。
内容的提问来源于stack exchange,提问作者Szymon Tymuła
相关产品推荐
相关产品推荐

