2014-10-14 12 views
7

Kiedy ten kod trafi w linię przekierowania, zgłasza "Nie można ustawić nagłówków po ich błędzie" i nie przekierowuje. Jestem winny, że nie w pełni rozumiem nagłówki i jak działa ekspres z nimi. This link about this error trochę mnie dezorientuje, prawdopodobnie dlatego, że nie mam dość podstawowej wiedzy na temat tego, co się dzieje. Ponadto, wiem, że jest to trochę naiwne podejście do uwierzytelniania, ale staram się tylko, żeby podstawowe rzeczy działały.Błąd przekierowania ekspresowego: nie można ustawić nagłówków po ich wysłaniu.

app.post('/api/login', function(req, res) { 
    if (req.body.password === auth.password) { 
     auth.date = new Date() 
     res.redirect('/admin') 
     } else { 
     console.log("wrong pw") 
     } 
    }) 

UPDATE: dziękuję @Brendan Ashworth Tęskniłem oczywistym innego, który dodałem teraz i nie pojawia się błąd.

jednak ta linia nie zmienia zawartość mojej stronie

res.sendfile('./public/admin/views/tunes.html') 

to działało zanim owinął je ze sprawdzianem auth

var auth = require('../config/auth') 

module.exports = function(app) { 

/* 
* CONTENT API 
*/ 

//... 

/* 
* Admin Routes 
*/ 
app.get('/admin/login', function(req, res) { 
    res.sendfile('./public/admin/views/login.html') 
}) 

app.post('/api/login', function(req, res) { 
    if (req.body.password === auth.password) { 
     auth.date = new Date() 
     res.redirect('/admin') 
    } else { 
     res.json({message: 'Wrong password!'}) 
    } 
}) 

app.get('/admin', function(req, res) { 
    if (auth.date) { 
     res.sendfile('./public/admin/views/tunes.html') 
     console.log("test") // 
    } else { //added else 
     res.redirect('/admin/login') 
    } 
}) 

app.get('/admin/:url', function(req, res) { 
    if (auth.date) { 
     res.sendfile('./public/admin/views/' + req.params.url + '.html') 
    } else { //added else 
     res.redirect('/admin/login') 
    } 
}) 

// frontend routes 
// route to handle all angular requests 
app.get('*', function(req, res) { 
    res.sendfile('./public/views/index.html') 
}) 

}

FINAL UPDATE !! Ostatnią rzeczą, której potrzebowałem, było obsłużenie strony przekierowania po wysłaniu pliku. Proste uwierzytelnianie działa teraz idealnie!

$http.post('/api/login', $scope.auth).success(function() { 
     window.location.href = '/admin' 
    }) 
+0

Czy możesz pokazać pozostałe trasy i oprogramowanie pośrednie? Warto również zauważyć, że jeśli res.body.password nie jest równe auth.password, to nigdy nie wyślesz odpowiedzi w opublikowanym przez ciebie kodzie. – Paul

+0

Czy masz inną trasę lub oprogramowanie pośrednie przed tą, która wywołuje 'res.writeHead()', 'res.send()', 'res.write()' lub coś podobnego? – mscdex

+0

@Paul Dzięki, zmienił konsolę.log na res.json, również zawiera więcej kodowanych – azium

Odpowiedz

7

Wyjaśnienie błędu Can't set headers after they are sent error:

Wszystkie odpowiedzi HTTP śledzić tę podstawową strukturę:

.. Response Line .. 
.. Headers .. 

.. Body .. 

Jeśli chcesz przekierować użytkownika, najpierw Response Line zostanie wysłany z przekierowaniem kod (powiedzmy 300), następnie Headers zostanie wysłany z nagłówkiem Location: xxx.

Następnie możemy wreszcie wysłać ciało (nie w przypadku przekierowania, ale ogólnie). Jednak - w przypadku Twojego kodu - wysyłasz odpowiedź Body, a następnie próbując przekierować użytkownika. Ponieważ nagłówki (i linia odpowiedzi) zostały już wysłane (ponieważ wysłałeś ciało), nie może wysłać więcej nagłówków po ciele.

Przykładem tego w kodzie byłoby:

app.get('/admin', function(req, res) { 
    if (auth.date) { 
     res.sendfile('./public/admin/views/tunes.html') 
    } 
    res.redirect('/admin/login') 
}) 

Jeśli mam rację zakładając, rzeczywiście chcesz return po wywołaniu res.sendfile(). Jeśli auth.date jest zgodne z prawdą, to wyślesz plik (np. Odpowiedź ciała), a następnie podasz kod przekierowania - to nie zadziała.

+0

Wierzę, że idzie nagłówek -> Ciało http://tools.ietf.org/html/rfc2616 –

+1

Sam nie jest tym, co umieszczam ? –

Powiązane problemy