2015-09-23 17 views
6

Niedawno wykonałem prosty samouczek dotyczący budowania serwera Express (https://codeforgeek.com/2014/06/express-nodejs-tutorial/).Serwer Express - nie można POST/

Próbuję rozszerzyć kod z tego samouczka, aby móc odpowiadać na żądania postów. Chcę zrobić to poprzez aktualizację pliku json (który zdarza się być wypełnione "komentarze użytkownika, a następnie rerendering w '/'

./server.js:

var express = require('express'); 
var app = express(); 

// routing configuration 
require('./router/main')(app); 

// ejs configuration 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'ejs'); 
app.engine('html', require('ejs').renderFile); 

// run the server 
var server = app.listen(8080, function(){ 
    console.log('Express server listening on port 8080'); 
}); 

. /router/main.js (router):

var fs = require('fs'); 
var ejs = require('ejs') 

module.exports = function(app){ 

    app.get('/', function(req, res){ 
    var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json')); 
    res.render('index.ejs', comments); 
    }); 

    app.post('/', function(req, res){ 
    console.log('here in post'); 
    var name = req.body.name; 
    var message = req.body.message; 
    var newComment = {"name": name, "message": message}; 
    var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json')); 
    comments.push(newComment); 
    fs.writeFileSync(__dirname + '/../comments.json', comments, 'utf8'); 
    //redirect to a 'get' on '/' 
    res.redirect('/'); 
    }); 

    app.get('/about', function(req, res){ 
    res.render('about.html') 
    }); 

} 

./views/index.ejs:

<div> 

    <div> 
    <h1> Joe's Forum </h1> 
    <a href='/about'> (about) </a> 
    </div> 

    <div> 
    <ul> 
    <% comments.forEach(function(comment){ %> 
     <li> 
     <%= comment.name %> : <%= comment.message %> 
     </li> 
    <% }); %> 
    </ul> 
    </div> 

    <h2> Enter a new comment </h2> 

    <form action='/' method="post"> 
    Enter your name: <input type='text' name='name'> <br><br> 
    Enter your message: <input type='textarea' name='message'> <br><br> 
    <input type='submit' value='Submit'> 
    <form> 

</div> 

./comments.json:

{ 
    "comments": [ 
    {"name":"Joe", "message" : "What advantages does Node.js afford the web developer?"}, 
    {"name": "John", "message": "Asynchronous IO helps us to keep our pages responsive even if the server is fetching data"} 
    ] 
} 

Kiedy próbuję złożyć nowy komentarz z mojej formy, wszystko co widzę to w ten sposób:

"Nie można POST /"

Czy ktoś może wyjaśnić, dlaczego dostaję tego błędu? Dzięki

+0

robisz coś rzeczywistego nie-nie. Nigdy nie powinieneś nigdy używać api 'Sync' programu nodeJS iz pewnością nie w odpowiedzi z serwera ekspresowego. Nie ma również żadnego sprawdzania błędów w dowolnym miejscu, więc serwer będzie bardzo podatny na awarie. Czy możesz pokazać zawartość 'comments.json'? – caasjj

+0

OK, wystarczy. Jednak po prostu chciałem "sprawić, by działało" jako ćwiczenie w pochylonej Expressie. Wiem, że to nie jest świetny kod. Kiedy otrzymam "żądanie postu", zamierzam go wyczyścić (tj. Zasubskrybować najlepsze praktyki). Zgodnie z żądaniem będę edytować, aby uwzględnić komentarze.json. –

+0

Nie było w ogóle krytyki - wystarczy wskazać coś, czego być może nie wiesz. Teraz myślę, że rozumiem też, dlaczego twój kod źle się zachowuje. Robisz 'comments.push' na' Object' - zamiast "Array". Zobaczę, czy uda mi się uzyskać dla ciebie jasną odpowiedź. – caasjj

Odpowiedz

3

Istnieje kilka problemów, ale głównym jest to, że nie masz analizatora treści - modułu, który konwertuje strumień węzłów w POST na req.body. Obecnie jestem zaznajomiony tylko z bodyParser i prawdopodobnie powinieneś to trochę zbadać. Chociaż jest to pokazane w dokumentacji Express 4.x, po uruchomieniu serwera pojawia się komunikat o wycofaniu.

Innym problemem jest wydanie numeru comments.push. To powinno być comments.comments.push. Następujące prace:

router.js:

var fs = require('fs'); 
var ejs = require('ejs') 

module.exports = function(app){ 

    app.get('/', function(req, res){ 
    var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json')); 
    res.render('index.ejs', comments); 
    }); 

    app.post('/', function(req, res){ 
    console.log('here in post'); 
    console.log(req.body) 
    var name = req.body.name; 
    var message = req.body.message; 
    var newComment = {"name": name, "message": message}; 
    var comments = JSON.parse(fs.readFileSync(__dirname + '/../comments.json')); 
    comments.comments.push(newComment); 
    fs.writeFileSync(__dirname + '/../comments.json', JSON.stringify(comments), 'utf8'); 
    //redirect to a 'get' on '/' 
    res.redirect('/'); 
    }); 

    app.get('/about', function(req, res){ 
    res.render('about.html') 
    }); 

} 

i server.js:

var express = require('express'); 
var bodyParser = require('body-parser'); 
var app = express(); 

app.use(bodyParser.urlencoded()) 

// routing configuration 
require('./router/main')(app); 

// ejs configuration 
app.set('views', __dirname + '/views'); 
app.set('view engine', 'ejs'); 
app.engine('html', require('ejs').renderFile); 

// run the server 
var server = app.listen(8080, function(){ 
    console.log('Express server listening on port 8080'); 
}) 
+0

Dzięki za odpowiedź. Kiedy zdobędę 15 punktów reputacji, zrobię to. –

+0

Doceniam to!Proszę spojrzeć na problem parsowania ciała i oprogramowania pośredniego w ogóle, ponieważ będzie to bardzo pouczające dla sposobu działania Express. – caasjj

Powiązane problemy