ReactJS + Node.js Express 后端Postman测试出现[err_http_headers_sent]错误求助
ERR_HTTP_HEADERS_SENT Error in Your Express Signup Route Hey there, I totally get how frustrating it is to be stuck on this error for two weeks—let's zero in on what's causing it in your code.
The Root Cause
Looking at your signuproute.js code, the issue is duplicate response attempts. When a user already exists (the if (user) block triggers), you send a 409 status code with res.sendStatus(409)—but you don't stop the rest of the function from running!
After sending that 409 response, the code continues to hash the password, insert a new user into the database, and then try to send a 200 response with the JWT token. By this point, the response headers have already been sent to the client, hence the ERR_HTTP_HEADERS_SENT error.
The Fix
You need to terminate the function execution right after sending the 409 response. There are two clean ways to do this:
Option 1: Add return after res.sendStatus(409)
export const signUpRoute = { path: '/api/signup', method: 'post', handler: async (req, res) => { const { email, password } = req.body; const db = getDbConnection('react-auth-db'); const user = await db.collection('users').findOne({ email }); if (user) { res.sendStatus(409); return; // Stop the function here to avoid duplicate responses } const passwordHash = await bcrypt.hash(password, 10); const startingInfo = { hairColor: '', favoriteFood: '', bio: '', }; const result = await db.collection('users').insertOne({ email, passwordHash, info: startingInfo, isVerified: false, }); const { insertedId } = result; jwt.sign({ id: insertedId, email, info: startingInfo, isVerified: false, }, process.env.JWT_SECRET, { expiresIn: '2d' }, (err, token) => { if (err) { return res.status(500).send(err); } res.status(200).send({ token }); }); } }
Option 2: Wrap the rest of the code in an else block
export const signUpRoute = { path: '/api/signup', method: 'post', handler: async (req, res) => { const { email, password } = req.body; const db = getDbConnection('react-auth-db'); const user = await db.collection('users').findOne({ email }); if (user) { res.sendStatus(409); } else { const passwordHash = await bcrypt.hash(password, 10); const startingInfo = { hairColor: '', favoriteFood: '', bio: '', }; const result = await db.collection('users').insertOne({ email, passwordHash, info: startingInfo, isVerified: false, }); const { insertedId } = result; jwt.sign({ id: insertedId, email, info: startingInfo, isVerified: false, }, process.env.JWT_SECRET, { expiresIn: '2d' }, (err, token) => { if (err) { return res.status(500).send(err); } res.status(200).send({ token }); }); } } }
Additional Tips to Prevent This in the Future
- Always ensure that after sending a response (with
res.send,res.sendStatus,res.json, etc.), you terminate the function execution usingreturnor structure your code with conditionals (likeelse) to avoid further code running. - Wrap your async operations in
try/catchblocks to handle unexpected errors and prevent unhandled promise rejections that could also lead to response issues:handler: async (req, res) => { try { // Your existing route logic here } catch (err) { res.status(500).send({ error: err.message }); } } - Double-check all your route handlers and middleware to make sure there's no other place where responses might be sent multiple times.
内容的提问来源于stack exchange,提问作者Matt Dolly

