2016-09-10 2 views
-1

Der Fehler in FrageFehler: nicht Header gesetzt, nachdem sie passportjs/Express

Error: Can't set headers after they are sent.

server.js

// set up ====================================================================== 
var express = require('express') 
    , app = express() 
    , cookieParser = require('cookie-parser') 
    , bodyParser = require('body-parser') 
    , expressSession = require('express-session') 
    , server = require('http').createServer(app) 
    , passport = require('passport') 
    , local = require('passport-local').Strategy 
    , md5 = require('md5') 
    , util = require('util') 
    , flash = require('connect-flash') 
    , port = 80 
    , url = require('url') 
    , db = require('./db'); 

// optimization ================================================================ 
var compress = require('compression'); 
app.use(compress()); 

// configuration =============================================================== 
app.use(express.static('public')); 
app.use(cookieParser()); 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'ejs'); 

app.use(bodyParser.urlencoded({ 
    extended: true 
})); 
app.use(bodyParser.json()); 

app.use(expressSession({ 
    secret: 'key', 
    resave: false, 
    saveUninitialized: false 
})); 
app.use(passport.initialize()); 
app.use(passport.session()); 
app.use(flash()); 

// passport ==================================================================== 
passport.use(new local(
    function(username, password, done) { 
     // asynchronous verification, for effect... 
     process.nextTick(function() { 
      db.findUserByName(username, function (err, user) { 
       if (err) { done(err); } 
       if (!user) { done(null, false, {message: 'Unknown user: ' + username})} 
       if (md5(password) == user.password) { 
        done(null, user); 
       } else { 
        done(null, false, {message: 'Invalid username or password'}); 
       } 
      }); 
     }); 
    } 
)); 
passport.serializeUser(function(user, done) { 
    done(null, user.uuid); 
}); 

passport.deserializeUser(function (id, done) { 
    db.findUserByUUID(id, done); 
}); 

// routes ====================================================================== 
require('./routes')(app, passport); 

// launch ====================================================================== 
server.listen(port, function(){ 
    console.log('server started'); 
}); 

routes.js

var flash = require('connect-flash'); 

module.exports = function(app, passport) { 

    app.get('/', function(req, res) { 
     res.render('index', { num: 0, logged: false }); 
    }); 

    app.get('/login', function (req, res) { 
     if (typeof req.user !== 'undefined') { 
      // User is logged in. 
      res.redirect('/'); 
     } else { 
      req.user = false; 
      var message = req.flash('error'); 
      if (message.length < 1) { 
       message = false; 
      } 
      res.render('login', { logged: false, message: message }); 
     } 
    }); 

    app.post('/login', 
     passport.authenticate('local', { 
      failureRedirect: '/login', 
      failureFlash: true 
     }), 
     function(req, res) { 
      res.redirect('/'); 
     } 
    ); 

    app.get('/logout', function(req, res){ 
     req.logout(); 
     res.redirect('/'); 
    }); 


}; 
gesendet werden, unter Verwendung von

db.js

var MongoClient = require('mongodb').MongoClient; 
var assert = require('assert'); 
var ObjectId = require('mongodb').ObjectID; 
var url = 'mongodb://localhost:27017/db'; 

exports.findUserByName = function (username, callback) { 
    MongoClient.connect(url, function(err, db) { 
     var cursor = db.collection('players').find({ "name": username }); 
     cursor.each(function(err, doc) { 
      if (doc != null) { 
       console.log('YES'); 
       callback(false, doc) 
      } else { 
       console.log('NO'); 
       callback(false, null); 
      } 
      db.close(); 
     }); 

    }); 
}; 

var findUserByUUID = function(uuid, db, callback) { 
    var cursor = db.collection('players').find({ "uuid": uuid }); 
    cursor.each(function(err, doc) { 
     assert.equal(err, null); 
     if (doc != null) { 
      callback(false, doc) 
     } else { 
      callback(false, null); 
     } 
    }); 
}; 
exports.findUserByUUID = function (uuid, callback) { 
    MongoClient.connect(url, function(err, db) { 
     assert.equal(null, err); 
     findUserByUUID(uuid, db, function(err, data) { 
      callback(err, data); 
      db.close(); 
     }); 
    }); 
}; 

Ich verstehe, dass ich zweimal fertig bin() aufgerufen wird, aber wann? Ich kann es nicht finden. Ich nehme an, dass das Problem auf den Routen ist, aber ich weiß nicht wo.

+0

Schauen Sie sich [diese] (http://stackoverflow.com/questions/7042340/node-js-error-cant-set-headers-after-they-are-sent) an und sehen Sie, ob das Ihr Problem lösen kann. – baranskistad

Antwort

0

In Ihrem Handler passport.use(), jedes Mal, wenn Sie done() aufrufen, müssen Sie dann return, damit der Code danach nicht auch ausgeführt wird.

Gerade jetzt haben Sie eine Reihe von Aussagen, die ifdone() jeder nennen können, aber sie sind nicht if/else Aussagen so mehr als eine Bedingung für die Sie testen erfüllt werden kann und somit done() kann mehr als einmal aufgerufen werden.

Zum Beispiel ändern diese:

if (!user) { done(null, false, {message: 'Unknown user: ' + username})} 

dazu:

if (!user) { 
    done(null, false, {message: 'Unknown user: ' + username}); 
    return; 
} 

Und, ändern Sie diese:

if (err) { done(err); } 

dazu:

if (err) { 
    done(err); 
    return; 
} 

Oder Sie könnten alles in if/else if/else if/else so machen, dass nur ein Zweig jemals ausgeführt werden könnte. Das Problem tritt auf, wenn mehr als eine Ihrer if-Anweisungen die Bedingung erfüllt hat und dann ausgeführt wird.


nun Ihre findUserByName() ruft seinen Rückruf in cursor.each() so kann sie es mehrmals aufrufen, die dann bewirkt, dass Sie done() mehrmals aufrufen.

+0

Ich habe alles in eine if/else if/else if/else-Anweisung geändert, aber ich bekomme immer noch den gleichen Fehler. Ich habe den DB-Code gepostet. – bernatixer

+0

@bernatixer - Ihr 'findUserByName()' ruft seinen Callback in 'cursor.each()' auf, so dass er mehrmals aufgerufen werden kann, was dazu führt, dass Sie 'done()' mehrmals aufrufen. – jfriend00

+0

Vielen Dank, es hat funktioniert – bernatixer

Verwandte Themen