ExpressJS中res.render/res.send不是函数问题求助
问题分析与解决方法
核心错误原因
你在conn.query的回调函数里用了res作为参数,这直接覆盖了外层Express的响应对象res。回调里的res其实是数据库查询返回的结果集合,不是Express用来处理响应的res对象,所以调用res.send()时会提示“res.send is not a function”。
其他潜在问题
- 回调函数中,当查询结果为空时,你先后调用
res.send()和res.render(),这会触发“Cannot set headers after they are sent to the client”错误——一个HTTP请求只能发送一次响应。 - 函数最后一行的
res.render('login', {param: 0})会在数据库查询完成前就执行,导致不管查询结果如何,都会先渲染login页面,后续回调里的渲染操作又会触发重复响应错误。
修正后的代码
exports.index = (req, res) => { // condition #1 if(req.body.username == '' || req.body.password == '') { res.render('login', { title: "Empty data", param: 1 }) return } // condition #2 const username = sanitize(req.body.username) const password = sanitize(req.body.password) const sql = "select username from tbl_user where username = ? LIMIT 1" // 把回调参数的res改成results,避免覆盖外层的Express响应对象 conn.query(sql, [username], function (err, results) { // 优先处理数据库查询错误 if (err) { return res.render('login', { param: 1, error: "数据库查询出错" }) } if(results.length == 0) { // 只返回一次响应,加return终止后续逻辑 return res.render('login', { param: 1, error: "username not found" }) } // 查询到用户,渲染主页面 res.render('../views/main/index', { param: 1 }) }) }
关键修正点
- 将
conn.query回调的参数res改为results(或其他任意不冲突的名称),确保外层Express的res响应对象能正常使用。 - 每个响应分支结束后添加
return,避免重复发送响应。 - 移除函数最后一行的
res.render,它会在异步查询完成前执行,导致逻辑混乱。 - 增加数据库查询错误的处理逻辑,避免未捕获的错误导致程序崩溃。
内容的提问来源于stack exchange,提问作者Bapholin
相关产品推荐
相关产品推荐

