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

使用Express.js与PostgreSQL时遭遇ERR_HTTP_HEADERS_SENT错误求助

解决Express.js中ERR_HTTP_HEADERS_SENT错误:确保仅发送一次响应

问题背景

使用Express.js和PostgreSQL开发时,数据能成功插入数据库,但出现Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client错误,已知是多次发送HTTP响应导致,但无法实现仅发送一次响应。

原代码问题分析

原代码存在多处导致重复响应的问题:

  • 字段校验和邮箱格式校验发送响应后未终止函数,代码会继续执行后续逻辑
  • 同时使用await和回调函数处理pool.query,触发两次响应发送逻辑
  • 函数末尾存在多余的res.send语句,无论前面是否发送响应都会执行

修改后的代码

const newAdmin = async (req, res) => {
  const { admin_name, admin_password, first_name, last_name } = req.body;

  // 校验必填字段,发送响应后立即终止函数
  if (!admin_name || !admin_password || !first_name || !last_name) {
    return res.status(400).send("You missed a required field");
  }

  const re = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@(([^<>()\[\]\.,;:\s@"]+\.)+[^<>()\[\]\.,;:\s@"]{2,})$/i;
  // 校验邮箱格式,发送响应后立即终止函数
  if (!re.exec(admin_name)) {
    return res.status(400).send("Email is not in proper form");
  }

  try {
    // 使用参数化查询避免SQL注入,仅用await处理异步逻辑
    const admin = await pool.query(
      "INSERT INTO admin(admin_name, admin_password, first_name, last_name) VALUES($1, $2, $3, $4)",
      [admin_name, admin_password, first_name, last_name]
    );

    // 成功插入后发送响应并终止函数
    return res.status(200).json("Insert into table successfully");
  } catch (e) {
    console.log(e);
    // 捕获错误后发送响应并终止函数
    return res.status(400).json("Failed to insert admin");
  }
};

关键修改说明

  • 终止函数执行:所有发送响应的语句后添加return,确保代码不会继续执行后续的响应逻辑
  • 统一异步处理方式:移除pool.query的回调函数,仅使用await处理异步操作,避免重复触发响应
  • 移除多余响应语句:删除原代码中res.send("Hello")和末尾的res.send("This works"),避免无意义的重复响应
  • 参数化查询优化:将SQL语句改为占位符形式,使用请求体的真实数据,同时避免SQL注入风险
  • 错误处理优化:错误捕获时先打印错误信息再发送响应,便于排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:24:53