2016-08-31 2 views
0

Ich schaute auf vorherige Antworten auf diese Frage, aber ich verstehe nicht, warum dieser Fehler auftritt, wenn res.send() in mehreren Pfaden vorhanden sind.Header können nicht festgelegt werden, nachdem sie in Express gesendet werden js

Mein Code so etwas wie diese (Express.js 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(); 
} 

Wenn ich nichts von meinem Frontend senden erhalte ich die 400 und die Fehlermeldung, aber mein Server zeigt dies:

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) 

Ich bin nicht sicher, wie ich Kopfzeilen nach dem Senden einer Antwort einstellen.

Antwort

4

Achten Sie darauf, zurückzukehren!

return res.status(400).end('Must send a user and pass'); 
+0

Das macht Sinn. Ich nehme an, wenn ich res.send() oder res.end() sage, stoppt die Ausführung dort und es wird standardmäßig zurückgegeben. –

+0

Die Antwort wird beendet, aber der Code danach wird noch ausgeführt werden http://expressjs.com/en/api.html#res.end –

+0

Um das hinzuzufügen, ist alles in Express 'Middleware', auch der letzte Rückruf getan. In dem Moment, in dem Sie 'next()' in Ihrer 'authenticate'-Middleware aufrufen, läuft der Callback (auch Middleware), den Sie in router.post angegeben haben, und versucht'res.send' auch auszuführen, obwohl die Antwort bereits erfolgt ist senden und das verursacht den Fehler. – CreasolDev

1

Ihnen fehlen einige Return-Anweisungen. Wenn Sie nicht von der Funktion zurückkehren status und send wird mehrmals auf Ihrem response Objekt aufgerufen, und am Ende wird auch next aufgerufen, so dass die kommenden Middlewares auf die Antwort zu arbeiten.

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(); 
} 
2

In Ihrer Middleware-Funktion, müssen Sie sicherstellen, dass next(), nachdem Sie eine Antwort (zum Beispiel durch den Aufruf res.send(), res.end() oder ähnliches) haben bereits genannt nicht gesendet.

Die einfachste Lösung ist, einfach von Ihrer Middleware Rückgaberecht, nachdem Sie eine Antwort gesendet haben:

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(); 
} 
0

Bitte stellen Sie sicher, return-Anweisung nach diesem Code

res.status(400).end('Must send a user and pass'); 

Es kann hinzufügen

return; or return res.status(400).end('Must send a user and pass'); 

Geben Sie einfach alles nach dieser Zeile zurück, im Grunde stoppen Sie die Ausführung Ihrer Co danach.

Verwandte Themen