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

Express服务器出现ERR_HTTP_HEADERS_SENT错误的排查求助

解决Express注册接口的ERR_HTTP_HEADERS_SENT错误

错误原因分析

你的代码存在两个核心问题引发该错误:

  • 提前调用done():路由处理函数中,你在异步的register(req, res)操作未完成时就直接执行了done(),这会让Express认为请求已处理完毕,提前结束响应。后续then回调里执行res.send()时,响应头已经发送,因此触发报错。
  • 响应结构不统一:userExists函数resolve的是布尔值(true/false),但路由回调期望的是带success和message属性的对象,这会导致响应数据异常,甚至引发其他逻辑问题。

修正后的代码

app.post('/register', (req, res) => {
    register(req, res).then((response) => {
        res.send({
            success: response.success,
            message: response.message
        });
    }).catch((error) => {
        console.log(error);
        // 补充错误响应,避免请求挂起
        res.status(500).send({
            success: false,
            message: error.message
        });
    });
    // 移除提前调用的done()
});


function register(req, res) {
    return new Promise((resolve, reject) => {
        if (req.body.password != req.body.confirmPassword) {
            resolve({
                success: false,
                message: "Passwords need to match."
            });
        } else {
            userExists(req.body.username).then((exists) => {
                if (exists) {
                    resolve({
                        success: false,
                        message: "Username already exists."
                    });
                } else {
                    // 此处可添加创建用户的逻辑,当前为成功示例
                    resolve({
                        success: true,
                        message: "Registration successful."
                    });
                }
            }).catch((error) => {
                reject({
                    success: false,
                    message: error.message
                });
            });
        }
    });
}


function userExists(username) {
    return new Promise((resolve, reject) => {
        findUser(username).then((response) => {
            resolve(response.length > 0);
        }).catch((error) => {
            reject(new Error(error.message));
        });
    });
}

function findUser(username) {
    return new Promise((resolve, reject) => {
        connection.query("SELECT * FROM users WHERE USERNAME=?", username, function(error, results, fields) {
            if (error) {
                reject(new Error(error.message));
            } else {
                resolve(results);
            }
        });
    });
}

关键修正说明

  • 移除done()调用:普通Express路由处理函数无需额外调用done(),异步操作完成后通过res.send()等方法结束请求即可。
  • 统一响应结构:修改userExists的调用逻辑,根据用户是否存在返回符合{success, message}格式的对象,确保路由回调的响应数据结构一致。
  • 补充错误响应:在catch回调中添加res.status(500).send(),避免请求挂起。
  • 简化参数传递:userExists无需接收req, res,直接传入username即可,减少不必要的参数依赖。

内容的提问来源于stack exchange,提问作者Pearl Lin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:24:57