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

ExpressJS中res.render/res.send不是函数问题求助

问题分析与解决方法

核心错误原因

你在conn.query的回调函数里用了res作为参数,这直接覆盖了外层Express的响应对象res。回调里的res其实是数据库查询返回的结果集合,不是Express用来处理响应的res对象,所以调用res.send()时会提示“res.send is not a function”。

其他潜在问题

  1. 回调函数中,当查询结果为空时,你先后调用res.send()和res.render(),这会触发“Cannot set headers after they are sent to the client”错误——一个HTTP请求只能发送一次响应。
  2. 函数最后一行的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:04:52