2016-05-02 9 views
0

Sagen Sie, ich habe diesen Code mit dem Router() von Express.Express mit dem Router() params

authRoute.param('token', function(req, res, next, token) { 
    User.findOne({ 'local.resetPasswordToken': req.params.token, resetPasswordExpires: { $gt: Date.now() }}, function(err, user) { 
     if (!user) { 
      req.flash('error', 'error msg here'); 
      return res.redirect('/forgot'); 
     } 
     req.user = user; 
    }) 
    next(); 
}) 

authRoute.route('/reset/:token') 
    .get(function(req, res) { 
     res.render('reset', { 
      user: req.user 
     }) 
    }) 

ich diesen Fehler:

_http_outgoing.js:346 
    throw new Error('Can\'t set headers after they are sent.'); 
    ^
Error: Can't set headers after they are sent. 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11) 

Ohne den Router(), das ist, wie es aussieht:

app.get('/reset/:token', function(req, res) { 
    User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) { 
    if (!user) { 
     req.flash('error', 'Password reset token is invalid or has expired.'); 
     return res.redirect('/forgot'); 
    } 
    res.render('reset', { 
     user: req.user 
    }); 
    }); 
}); 

Was bin ich mit der Router.param Seite falsch? Ich lese auf die Fehlermeldung, die gegeben wird, und ich lerne es passiert, wenn ein Versuch unternommen wird, Header für die Antwort zu setzen, die bereits festgelegt wurde.

Antwort

2

Sie next() in authRout.param Aufruf sofort, damit andere Middlelassen, irgendwann am Ende Aufruf res.end() (res.render, res.send, etc) vor dem Mongoose Rückruf aufgerufen wurde. Meine Annahme ist, dass Sie diesen Fehler bekommen, wenn Middleware ausgeführt wird (vorher erklärt) und dann res.redirect('/forgot') aufgerufen wird, nachdem eine der Middlewares die Antwort bereits "beendet" hat.

Die Lösung besteht darin, auf Ihre DB-Antwort zu warten, bevor Sie die Middleware-Kette herunterfahren, einfach ein asynchrones Problem. Betrachten Sie den folllowing:

authRoute.param('token', function(req, res, next, token) { 
    User.findOne({ 'local.resetPasswordToken': req.params.token, resetPasswordExpires: { $gt: Date.now() }}, function(err, user) { 
     // pass error to middlewares 
     if (err) return next(err) 
     // Stop the middleware chain i.e. return res.redirect 
     if (!user) { 
      req.flash('error', 'error msg here'); 
      return res.redirect('/forgot'); 
     } 
     req.user = user; 
     // important! call `next()` after mongo response 
     next() 
    }) 
}) 

Dies ist nicht im einzelnen Request-Handler geschieht (Ihr letztes Beispiel), weil Sie richtig async Handhabung sind - nicht enden die HTTP-Antwort vor dem Mongoose Rückruf aufgerufen wird.

+0

Danke, die Fehlermeldung ist weg und zeigt auf die '/ forgotten'-URL, was bedeutet, dass etwas nicht richtig funktioniert, was ein separates Problem ist, danke dieser Frage. Vielen Dank. – Rexford

+0

Gern geschehen, froh, dass ich helfen konnte! – Nindaff

Verwandte Themen