Ошибка Nodejs / Express: не удается установить заголовки после их отправки

#javascript #node.js #express #asynchronous #error-handling

#javascript #node.js #экспресс #асинхронный #обработка ошибок

Вопрос:

Довольно новичок в node / express. Я проверяю, существует ли пользователь (через имя пользователя) уже в базе данных, в которой требуется зарегистрироваться, выдавая ошибку, если они уже существуют.

Когда я использую curl, чтобы попытаться отключить его намеренно, я получаю следующую ошибку:

Ошибка: не удается установить заголовки после их отправки.

Я уже знаю, что первая проверка, которую я делаю, чтобы убедиться, что все поля заполнены правильно, работает и не создает проблем с многократной установкой заголовков.

Буду признателен за любую помощь.

(Мой соответствующий код приведен ниже. Если вам нужно что-нибудь еще, не стесняйтесь сказать об этом!)

 router.post('/register', function(req, res, next) {
    if(!req.body.username || !req.body.password){
        return res.status(400).json({ message: 'Please fill out all fields.' });
    }

    User.count({ username: req.body.username}, function(err, count){
        console.log(count);
        if(count > 0) {
            return res.status(400).json({message: 'This user already exists!' });
        }
    });

    var user = new User();

    user.username = req.body.username;
    user.setPassword(req.body.password);

    user.save(function(err) {
        if(err) { return next(err); }

        return res.json({ token: user.generateJWT()});
    });
});
  

Ответ №1:

Когда вы возвращаетесь внутри User.count и user.save, вы возвращаетесь только изнутри обратных вызовов, но не всего метода.

Хорошей практикой является отправка ответа только в одно место. В конце метода. Перед этим оцените свои условия и задайте код ответа и ответное сообщение в некоторой переменной. Который вы можете использовать для отправки ответа в качестве последнего шага.

Попробуйте это в качестве обходного пути на данный момент:

     router.post('/register', function(req, res, next) 
{
    if(!req.body.username || !req.body.password)
    {
        return res.status(400).json({ message: 'Please fill out all fields.' });
    }

    User.count({ username: req.body.username}, function(err, count)
    {
        console.log(count);
        if(count > 0) 
        {
            return res.status(400).json({message: 'This user already exists!' });
        }
        else
        {
            var user = new User();
            user.username = req.body.username;
            user.setPassword(req.body.password);

            user.save(function(err) 
            {
                if(err) 
                { 
                    return next(err); 
                }

                return res.json({ token: user.generateJWT()});
            });
        }
    });
});
  

Ответ №2:

Поместите весь ваш код в функцию обратного вызова User.count, в противном случае выполняются две части кода

  router.post('/register', function(req, res, next) {
    if(!req.body.username || !req.body.password){
       return res.status(400).json({ message: 'Please fill out all fields.' });
    }

    User.count({ username: req.body.username}, function(err, count){
    console.log(count);
    if(count > 0) {
        return res.status(400).json({message: 'This user already exists!' });
    }
    var user = new User();

    user.username = req.body.username;
    user.setPassword(req.body.password);

    user.save(function(err) {
      if(err) { return next(err); }

        return res.json({ token: user.generateJWT()});
     });
   });  
});