简体   繁体   English

“发送后无法设置标头”和空的发布请求正文

[英]"Can't set headers after they are sent" and empty post request body

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.每当我发送 POST 请求时,我都会收到错误“发送后无法设置标头”。 I tried to console.log the request body and it were empty.我试图 console.log 请求正文,它是空的。 I don't know where I did wrong.我不知道我哪里做错了。 Please help.请帮忙。

users.js用户.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应用程序.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更新 2 :错误日志

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. res.render在出现错误时发送响应。 After that again you are trying to send the headers via res.location and res.redirect .之后,您再次尝试通过res.locationres.redirect发送标头。

Move the res.redirect to the else block.res.redirect移动到 else 块。

  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
}


})

You are facing this because of :你面临这个是因为:

req.flash('sucess', 'You are now registered and may login'); //this is okay
res.location('/'); //[1]
res.redirect('/'); //[2]

[1] you are setting headers and redirecting to '/' route . [1]您正在设置标头并重定向到 '/' route

[2] you are setting headers passing status code: 302 and redirecting to '/' route. [2]您正在设置传递状态代码的标头:302 并重定向到“/”路由。

oh wait?等一下? didn't you already set headers in step 1?你不是已经在步骤 1 中设置了标题吗? Yes that's what the error means.是的,这就是错误的意思。 You can have only one response per request.每个请求只能有一个响应。 Use this for more info.使用获取更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM