Express+MySQL POST请求添加产品成功但报ERR_HTTP_HEADERS_SENT错误
问题现象
- 向MySQL发送POST请求添加产品,数据成功入库,但触发错误:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
错误栈信息
at new NodeError (node:internal/errors:387:5)
at ServerResponse.setHeader (node:_http_outgoing:603:11)
at ServerResponse.header (C:\Users\DELL\Desktop\Small project\node_modules\express\lib\response.js:794:10)
at ServerResponse.send (C:\Users\DELL\Desktop\Small project\node_modules\express\lib\response.js:174:12)
at Query. (C:\Users\DELL\Desktop\Small project\server.js:47:16)
at Query. (C:\Users\DELL\Desktop\Small project\node_modules\mysql\lib\Connection.js:526:10)
at Query._callback (C:\Users\DELL\Desktop\Small project\node_modules\mysql\lib\Connection.js:488:16)
at Query.Sequence.end (C:\Users\DELL\Desktop\Small project\node_modules\mysql\lib\protocol\sequences\Sequence.js:83:24)
at Query._handleFinalResultPacket (C:\Users\DELL\Desktop\Small project\node_modules\mysql\lib\protocol\sequences\Query.js:149:8)
at Query.OkPacket (C:\Users\DELL\Desktop\Small project\node_modules\mysql\lib\protocol\sequences\Query.js:74:10) {
code: 'ERR_HTTP_HEADERS_SENT'}
相关代码
app.post("/product", (req, res, next) => { let product = { product_title: "lool", product_price: 4444.12, product_type: "sneakers", product_brand: "lol", }; let sql = `INSERT INTO products SET ?`; db.query(sql, product, (err, result) => { if (err) { throw err; } console.log(result); return res.send("Completed"); }); res.send("Added"); });
错误原因
Express规定每个HTTP请求只能发送一次响应头和响应体。你的代码里,db.query是异步操作,不会阻塞后续代码执行,所以res.send("Added")会先被调用,发送第一次响应;当数据库查询完成后,回调函数里又执行return res.send("Completed"),尝试第二次发送响应,这就触发了ERR_HTTP_HEADERS_SENT错误。
解决方案
移除db.query外部的res.send("Added"),确保只在数据库操作完成后发送一次响应。同时优化错误处理方式,避免直接抛出错误导致服务器崩溃:
app.post("/product", (req, res, next) => { let product = { product_title: "lool", product_price: 4444.12, product_type: "sneakers", product_brand: "lol", }; let sql = `INSERT INTO products SET ?`; db.query(sql, product, (err, result) => { if (err) { return res.status(500).send(err.message); } console.log(result); res.send("Completed"); }); });
内容的提问来源于stack exchange,提问作者user19347248

