I've been following a tutorial for a login/register authentication application. I keep getting the error "Can't set headers after they are sent" whenever I send POST requests. I tried to console.log the request body and it were empty. I don't know where I did wrong. Please help.
users.js
var express = require('express');
var router = express.Router();
var User = require('../models/User')
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register', function(req, res, next) {
res.render('register', {title:'Register'});
});
router.get('/login', function(req, res, next) {
res.render('login', {title: 'Login'})
});
router.post('/register', function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
if (req.files && req.files.profileimage) {
console.log('Uploading file...');
var profileimageOriginalName = req.files.profileimage.originalname;
var profileimageName = req.files.profileimage.name;
var profileimageMime = req.files.profileimage.mimetype;
var profileimageExt = req.files.profileimage.extension;
var profileimageSize = req.files.profileimage.size;
var profileimagePath = req.files.profileimage.path;
} else {
var profileimageName = 'noimage.png'
}
req.checkBody('name', 'Name field is required').notEmpty();
req.checkBody('email', 'Email field is required').notEmpty();
req.checkBody('email', 'Email field is not valid').isEmail();
req.checkBody('username', 'Username field is required').notEmpty();
req.checkBody('password', 'Password field is required').notEmpty();
req.checkBody('password2', 'Password does not match').equals(req.body.password);
var errors = req.validationErrors()
if (errors) {
res.render('register', {
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileimage: profileimageName
})
}
User.createUser(newUser, function(err, user) {
if (err) throw err;
console.log(user);
})
req.flash('sucess', 'You are now registered and may login');
res.location('/');
res.redirect('/');
})
module.exports = router;
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var passport = require('passport');
var LocalStrategry = require('passport-local').strategy;
var bodyParser = require('body-parser');
var expressValidator = require('express-validator');
var flash = require('connect-flash');
var multer = require('multer')
var mongo = require('mongodb');
var mongoose = require('mongoose');
var db = mongoose.connection
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// handle file upload
var upload = multer({dest: './uploads'});
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}))
app.use(passport.initialize());
app.use(passport.session());
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
app.use(flash())
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
UPDATE: If I remove the validator codes, the error will be gone, but the post request body still empty
UPDATW 2: Error log
POST /users/register 500 26.552 ms - 2629
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (F:\Projects\nodeauth\node_modules\express\lib\response.js:718:10)
at ServerResponse.send (F:\Projects\nodeauth\node_modules\express\lib\response.js:163:12)
at done (F:\Projects\nodeauth\node_modules\express\lib\response.js:957:10)
at Object.exports.renderFile (F:\Projects\nodeauth\node_modules\jade\lib\index.js:374:12)
at View.exports.__express [as engine] (F:\Projects\nodeauth\node_modules\jade\lib\index.js:417:11)
at View.render (F:\Projects\nodeauth\node_modules\express\lib\view.js:126:8)
at tryRender (F:\Projects\nodeauth\node_modules\express\lib\application.js:639:10)
at EventEmitter.render (F:\Projects\nodeauth\node_modules\express\lib\application.js:591:3)
at ServerResponse.render (F:\Projects\nodeauth\node_modules\express\lib\response.js:961:7)
at F:\Projects\nodeauth\app.js:99:7
at Layer.handle_error (F:\Projects\nodeauth\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:310:13)
at F:\Projects\nodeauth\node_modules\express\lib\router\index.js:280:7
at Function.process_params (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:330:12)
at next (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:271:10)
at Layer.handle_error (F:\Projects\nodeauth\node_modules\express\lib\router\layer.js:67:12)
at trim_prefix (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:310:13)
at F:\Projects\nodeauth\node_modules\express\lib\router\index.js:280:7
at Function.process_params (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:330:12)
at Immediate.next (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:271:10)
at Immediate.<anonymous> (F:\Projects\nodeauth\node_modules\express\lib\router\index.js:618:15)
You can not set the header after it has been sent to client.
res.render
sends the sends the response when there is error. After that again you are trying to send the headers via res.location
and res.redirect
.
Move the res.redirect
to the else block.
var multer = require('multer');
var upload = multer();
router.post('/register', upload.array(), function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
..................
if (errors) {
res.render('register', {
errors: errors,
name: name,
email: email,
username: username,
password: password,
password2: password2
});
} else {
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
profileimage: profileimageName
})
//now this is also in the else block
User.createUser(newUser, function(err, user) {
if (err) throw err;
console.log(user);
})
req.flash('sucess', 'You are now registered and may login');
res.location('/');
res.redirect('/');
//till here so you don't send response twice
}
})
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments