I looked around at previous answers to this question, but I don't understand why is this error coming up if there are res.send()
in multiple paths.
My code is something like this (expressjs 4.13):
var user ={
username: "some",
password: "a"
}
router.post('/login', authenticate, function (req, res) {
//if it passes the middleware, send back the user
var token = jwt.sign({
username: user.username
}, jwtSecret);
res.send({
token: token,
user: user
});
});
function authenticate(req, res, next) {
var body = req.body;
var username = body.username, password = body.password;
//if nothing is sent
if(!username || !password){
res.status(400).end('Must send a user and pass');
}
//if incorrect credentials are sent
if(username !== user.username || password !== user.password){
res.status(401).end("Incorrect credentials");
}
//if it reaches here, it means credentials are correct
next();
}
When I don't send anything from my frontend, I am getting the 400 and error message, but my server shows this:
POST /apis/auth/login 401 0.841 ms - -
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/response.js:718:10)
at ServerResponse.json (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/response.js:246:10)
at ServerResponse.send (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/response.js:151:21)
at /home/vivek/dev/qwiksplit/jsback/app.js:81:9
at Layer.handle_error (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/layer.js:71:5)
at trim_prefix (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:310:13)
at /home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:330:12)
at next (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:271:10)
I am not sure how I am setting headers after a response is sent.
确保退货!
return res.status(400).end('Must send a user and pass');
In your middleware function, you need to make sure next()
is not called after you've already sent a response (eg, by calling res.send()
, res.end()
or similar).
The simplest solution is to just return from your middleware right after you've sent a response:
function authenticate(req, res, next) {
var body = req.body;
var username = body.username, password = body.password;
if(!username || !password){
res.status(400).end('Must send a user and pass');
return; // <-----
}
if(username !== user.username || password !== user.password){
res.status(401).end("Incorrect credentials");
return; // <-----
}
next();
}
You are missing some return statements. If you don't return from the function status
and send
gets called multiple times on your response
object, and at the end even next
is called as well, so the upcoming middlewares will operate on the response too.
function authenticate(req, res, next) {
var body = req.body;
var username = body.username, password = body.password;
//if nothing is sent
if(!username || !password){
res.status(400).end('Must send a user and pass');
return;
}
//if incorrect credentials are sent
if(username !== user.username || password !== user.password){
res.status(401).end("Incorrect credentials");
return;
}
//if it reaches here, it means credentials are correct
next();
}
Please make sure to add return statement after this code
res.status(400).end('Must send a user and pass');
It can be
return; or return res.status(400).end('Must send a user and pass');
Just return anything after that line, basically stop execution of your code after that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.