使用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
相关产品推荐
相关产品推荐

