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

Node.js报错Cannot set headers after they are sent to the client求助

解决Node.js "Cannot set headers after they are sent to the client" 错误

你的问题出在extractUser中间件的逻辑漏洞上:当请求不存在userToken Cookie时,next()会被调用两次,导致后续控制器函数执行两次。第一次控制器发送响应后,第二次再尝试发送响应时,就会触发"Cannot set headers after they are sent to the client"错误。

问题代码分析

当!token为真时,你设置res.locals.user = null并调用next(),但没有终止函数执行,代码会继续进入后面的try块:

  • 此时token为undefined,jwt.verify(token, ...)会抛出错误,进入catch块,再次调用next()
  • 两次调用next()会让控制器函数执行两次,第一次发送响应后,第二次再执行res.status(200).json(...)或res.sendStatus(400)时,响应头已被发送,触发错误

修复后的中间件代码

只需在if(!token)分支的next()后添加return,终止函数后续逻辑执行;同时补充User.findById的错误捕获,避免未处理的Promise异常:

function extractUser(req, res, next) {
    let token = req.cookies.userToken;
    if (!token) {
        res.locals.user = null;
        return next(); // 添加return,阻止代码进入后续try块
    }
    try {
        let { id } = jwt.verify(token, SERVER_SECRET);
        if (id) {
            User.findById(id)
                .then(user => {
                    res.locals.user = user;
                    next();
                })
                .catch(err => { // 捕获数据库查询异常
                    res.locals.user = null;
                    next();
                });
        } else {
            res.locals.user = null;
            next();
        }
    } catch (err) {
        res.locals.user = null;
        next();
    }
}

也可以用else包裹后续逻辑,确保只有当token存在时才执行验证流程:

function extractUser(req, res, next) {
    let token = req.cookies.userToken;
    if (!token) {
        res.locals.user = null;
        next();
    } else {
        try {
            let { id } = jwt.verify(token, SERVER_SECRET);
            if (id) {
                User.findById(id)
                    .then(user => {
                        res.locals.user = user;
                        next();
                    })
                    .catch(err => {
                        res.locals.user = null;
                        next();
                    });
            } else {
                res.locals.user = null;
                next();
            }
        } catch (err) {
            res.locals.user = null;
            next();
        }
    }
}

内容的提问来源于stack exchange,提问作者M.KH

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:57:50