如果我使用send或json,节点应用程序崩溃

时间:2016-08-11 07:01:21

标签: node.js mongodb web-services crash nodes

我正在创建一个IOS应用程序,在后台我们使用了Node.js和Mongodb。我已经创建了用于创建用户的节点应用程序并通过jSon发送错误和成功响应,但是如果使用res.send我的节点应用程序将崩溃。 我试图找到问题,但没有得到积极的回应。在我的所有代码下面。

Controller :

const nodemailer    = require('nodemailer');
const passport      = require('passport');
const User          = require('../../models/User');





exports.ManuallySave = function(req,res)
{
  if(req.body.my_token !== '')
  {
    User.findOne({ email: req.body.email }, (err, existingUser) => {
      if (existingUser) 
      {
        //res.setHeader('Content-Type', 'text/plain');
        res.json({"status":'error',"msg":'Email address already exists.'});
      }
    });

    User.findOne({ username: req.body.username }, (err, existingUserName) => {
      if (existingUserName) 
      {
        res.send({"status":'error',"msg":'Username already exists.'});
      }
    });

    /* Save Action perform */
  }
  else 
  {
    res.send({"status":'error',"msg":'Token is not available.'});
  }

}

Console Error.

/var/www/node/MyApplication/node_modules/mongodb/lib/utils.js:98
    process.nextTick(function() { throw err; });
                                  ^

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
    at ServerResponse.header (/var/www/node/MyApplication/node_modules/express/lib/response.js:718:10)
    at ServerResponse.send (/var/www/node/MyApplication/node_modules/express/lib/response.js:163:12)
    at ServerResponse.json (/var/www/node/MyApplication/node_modules/express/lib/response.js:249:15)
    at ServerResponse.send (/var/www/node/MyApplication/node_modules/express/lib/response.js:151:21)
    at /var/www/node/MyApplication/controllers/apis/userAppController.js:55:13
    at model.<anonymous> (/var/www/node/MyApplication/node_modules/mongoose/lib/document.js:1875:20)
    at next_ (/var/www/node/MyApplication/node_modules/hooks-fixed/hooks.js:89:34)
    at fnWrapper (/var/www/node/MyApplication/node_modules/hooks-fixed/hooks.js:186:18)
    at /var/www/node/MyApplication/node_modules/mongoose/lib/model.js:226:5
    at /var/www/node/MyApplication/node_modules/mongoose/lib/model.js:135:7
    at /var/www/node/MyApplication/node_modules/mongodb/lib/collection.js:504:5
    at /var/www/node/MyApplication/node_modules/mongodb/lib/collection.js:666:5
    at handleCallback (/var/www/node/MyApplication/node_modules/mongodb/lib/utils.js:96:12)
    at /var/www/node/MyApplication/node_modules/mongodb/lib/bulk/unordered.js:473:9
    at handleCallback (/var/www/node/MyApplication/node_modules/mongodb/lib/utils.js:96:12)
    at resultHandler (/var/www/node/MyApplication/node_modules/mongodb/lib/bulk/unordered.js:420:5)
    at /var/www/node/MyApplication/node_modules/mongodb-core/lib/wireprotocol/2_4_support.js:544:17
    at nextTickCallbackWith0Args (node.js:420:9)
    at process._tickCallback (node.js:349:13)

我已经使用了res.send和res.json,但在这两种情况下我的应用程序都会崩溃。

3 个答案:

答案 0 :(得分:2)

当您在调用res时尝试调用res.send上的方法时,会引发该错误。我们无法保证只在您的代码中调用res.send一次,必须有。块

User.findOne({ email: req.body.email }, (err, existingUser) => {
  if (existingUser) 
  {
    //res.setHeader('Content-Type', 'text/plain');
    res.json({"status":'error',"msg":'Email address already exists.'});
  }
});

User.findOne({ username: req.body.username }, (err, existingUserName) => {
  if (existingUserName) 
  {
    res.send({"status":'error',"msg":'Username already exists.'});
  }
});
如果您的用户同时拥有该电子邮件地址和该用户名,则

将调用res.send两次。你必须在第一个回调中进行另一个电话。

User.findOne({ email: req.body.email }, (err, existingUser) => {
  if (existingUser) 
  {
    //res.setHeader('Content-Type', 'text/plain');
    res.json({"status":'error',"msg":'Email address already exists.'});
  } else {
    checkUsername();
  }
});
function checkUsername() {
  User.findOne({ username: req.body.username }, (err, existingUserName) => {
    if (existingUserName) 
    {
      res.send({"status":'error',"msg":'Username already exists.'});
    } else {
      // save action
    }
  });
}

我建议你研究promise chains来处理不可避免的即将召回的回调嵌套吗?

答案 1 :(得分:0)

您应该只使用或运算符。

 User.findOne({ $or: [ {  email: req.body.email }, { username: req.body.username } ] }, (err, existingUser) => {
  if (existingUser) 
  {
    //res.setHeader('Content-Type', 'text/plain');
    res.json({"status":'error',"msg":'Email address already exists.'});
  }
});

比你刚发送一个回复。

答案 2 :(得分:-1)

您收到此错误是因为您的代码在res.json()出现问题后允许res.send()。

您的两个验证检查都是异步执行的,如果满足两个验证条件,则将执行res.json和res.send。

一种解决方案是将第二个检查嵌入第一个回调中,如下所示:

const nodemailer    = require('nodemailer');
const passport      = require('passport');
const User          = require('../../models/User');

exports.ManuallySave = function(req,res){
    if(req.body.my_token !== ''){
        User.findOne({ email: req.body.email }, (err, existingUser) => {
            if (existingUser) {
                res.json({"status":'error',"msg":'Email address already exists.'});
            } else {
                User.findOne({ username: req.body.username }, (err, existingUserName) => {
                    if (existingUserName) {
                        res.send({"status":'error',"msg":'Username already exists.'});
                    } else {
                        /* Save Action perform */
                    }
                });
            }
        });
    } else  {
        res.send({"status":'error',"msg":'Token is not available.'});
    }
}

我还建议在这两个回调中检查错误并进行处理。