做出 POST 请求时的节点错误 [ERR_ HTTP_ HEADERS_ SENT]
原标题:Nodejs error when making a POST request [ERR_HTTP_HEADERS_SENT]
I am new to NODEJS / express , and I was following a tutorial to build a small MERN app. In the initial steps, while setting up a POST route, when sending a POST request with Postman, I am getting this Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client I´ve reading about it, and I somehow understand is because I am calling res.json two times in the same response.
My router is this :
router.post( /login ,
async (req, res) => {
try {
const user = await userModel.findOne({email:req.body.email});
!user && res.status(404).send("user not found");
const correctPassword = await bcrypt.compare(req.body.password, user.password);
!correctPassword && res.status(400).json( incorrect password )
res.status(200).json(user); // if not invalid return user
} catch (err) {
console.log(err)
}
})
I tried different solutions i found here (IF & if Else statements, using return ...) without any success. This very same code (with different variable names) is working flawless in mentioned tutorial.
Any idea how could I solve it? Thanks in advance.
EDIT : I add the resto of my user Route for completion ´´´
import express from express ;
const router = express.Router();
import bcrypt from bcrypt ;
import userModel from ../models/userModel.js
router.post( /register ,
async (req, res) => {
try {
// hash password
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt)
// Create New User
const newUser = new userModel({
userName: req.body.userName,
email: req.body.email,
password: hashedPassword,
});
// Save New User and return response
const user = await newUser.save();
res.status(200).json(user);
} catch(err){
console.log(err)
}
});
最佳回答
Likely user is falsy or correctPassword evaluates to false, which will send a response of "user not found" or "incorrect password".
However, it continues to execute the rest of your function and eventually executes this line
res.status(200).json(user);
This line will cause the error you ve mentioned, as you have already sent a response to the client previously and cannot send another response in the same request-response-cycle.
This should fix the issue:
router.post("/login", async (req, res) => {
try {
const user = await userModel.findOne({ email: req.body.email });
if (!user) {
return res.status(404).send("user not found");
}
const correctPassword = await bcrypt.compare(req.body.password, user.password);
if (!correctPassword) {
return res.status(400).json("incorrect password");
}
return res.status(200).json(user); // if not invalid return user
} catch (err) {
console.log(err);
return res.status(500).send(err.message);
}
});
I d recommend using ifs here, as it makes the code easier to read. I d also recommend using return anytime you send a response as it will avoid the issue you ran into.
问题回答
. Using Conditional Logic:
JavaScript
router.post( /login , async (req, res) => {
try (!user) {
res.status(404).send("user not found");
} else {
const correctPassword = await bcrypt.compare(req.body.password, user.password);
if (!correctPassword) {
res.status(400).json( incorrect password );
} else {
res.status(200).json(user);
}
}
} catch (err) {
console.log(err);
}
});
Here, you use if...else statements to control the flow of the response based on the conditions. The first valid condition triggers the appropriate response, and the code continues no further.
const register =async(req, res)=> {
try{ res.status(400).json("Weclocme in regstrer page");
} catch(error) {
res.status(200).send("Page not found ");
Using return Statements:
router.post( /login , async (req, res) => {
try {
const user = await userModel.findOne({ email: req.body.email });
if (!user) {
return res.status(404).send("user not found");
// Early return if user not found
}
const correctPassword = await bcrypt.compare(req.body.password, user.password);
if (!correctPassword) {
return res.status(400).json( incorrect
password ); // Early return if password is incorrect
}
res.status(200).json(user); // Send successful login response only if both conditions pass
} catch (err) {
console.log(err);
}
});
In this approach, return statements are used after sending error responses. Once a response is sent, the function stops executing, preventing further attempts to modify headers or send additional responses.
相关问题
Is it possible to deploy a Django project with MongoDB to AWS?
How can I deploy a Django project that uses MongoDB to AWS?
I have a project made using Django and have been using MongoDB and its Compass app and was wondering if you could deploy said project and ...
Access DB Ref MongoDB
Whats the best way to access/query a DB Ref:
UPDATE:
users: name, groupref : {$ref:"groups",$id:"ObjectId ..." } }
groups: name, topic, country,...,..
Assumption is that user belongs to only one ...
MongoDB: Is it possible to make a case-insensitive query?
Example:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
MongoDB nested sets
What re the best practices to store nested sets (like trees of comments) in MongoDB?
I mean, every comment can have a parent comment and children-comments (answers).
Storing them like this:
{
...
Middleware for MongoDB or CouchDB with jQuery Ajax/JSON frontend
I ve been using the following web development stack for a few years:
java/spring/hibernate/mysql/jetty/wicket/jquery
For certain requirements, I m considering switching to a NoSQL datastore with an ...
MongoMapper and migrations
I m building a Rails application using MongoDB as the back-end and MongoMapper as the ORM tool. Suppose in version 1, I define the following model:
class SomeModel
include MongoMapper::Document
...
MongoDB takes long for indexing
I have the following setup:
Mac Pro with 2 GB of RAM (yes, not that much)
MongoDB 1.1.3 64-bit
8 million entries in a single collection
index for one field (integer) wanted
Calling .ensureIndex(...) ...
Storing and accessing large amounts of data
My application creates pieces of data that, in xml, would look like this:
<resource url="someurl">
<term>
<name>somename</name>
<frequency>somenumber</...