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

登录接口输错账号/密码时崩溃,报错Cannot set headers after they are sent to the client

登录接口崩溃问题排查与修复

问题根源

你的代码核心问题是错误响应发送后未终止函数执行,导致后续代码继续运行并重复发送HTTP响应,触发Cannot set headers after they are sent to the client错误:

  • 当用户名不存在时,!user && res.status(401).json(...)发送了401响应,但函数没有停止,接下来会尝试访问undefined的user.password,最终进入catch块再次发送500响应,造成重复响应。
  • 当密码错误时,发送401响应后,后续生成token、发送200响应的代码依然会执行,导致两次响应冲突。

修复后的代码

// Authentication
router.post("/login", async (req, res) => {
    try{
        const user = await User.findOne({username: req.body.username});
        // 用户名不存在时,发送响应后终止函数
        if (!user) {
            return res.status(401).json("User not found.");
        }

        const hashedPassword = CryptoJs.AES.decrypt(user.password, process.env.SECRET);
        const originalPassword = hashedPassword.toString(CryptoJs.enc.Utf8);

        // 密码错误时,发送响应后终止函数
        if (originalPassword !== req.body.password) {
            return res.status(401).json(`Incorrect username or password`);
        }

        const token = jwt.sign({
            id: user.id,
            isAdmin: user.isAdmin,
        }, process.env.JWT_SECRET, { expiresIn: "3d" });

        const {password, ...otherParams} = user._doc;

        res.status(200).json({...otherParams, token});

    } catch(e) {
        res.status(500).json("ERROR ERROR ERROR " + e);
    }
})

关键修改说明

  • 用显式if判断替换原来的短路逻辑(&&),并在发送错误响应后调用return,确保函数立即停止执行,彻底避免后续代码重复发送响应。
  • 这种写法逻辑更清晰,也符合Node.js HTTP响应的规范:每个请求只能发送一次响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:15:28