如何处理发送后无法设置标头

时间:2016-02-26 15:05:58

标签: node.js express

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({
    tel: {
       type: Number,
       unique: true
    },
    name: String,
    hash_password: String,
    created_at: Date
}, {
   collection: 'users'
});

var User = mongoose.model('User', UserSchema);

module.exports = User;

login.js

var crypto = require('crypto');
var express = require('express');
var jwt = require('jsonwebtoken');
var router = express.Router();
var User = require('../modules/user');
var Token = require('../modules/token');

router.get('/', function(req, res,next) {
   res.render('login', {
       title: '登录界面'
   });
   next();
});

router.post('/', function(req, res) {
    User.findOne({
        tel: req.body.tel,
    })
    .exec(function(err, user) {
        var md5 = crypto.createHash('md5'),
            password = md5.update(req.body.password)
            .digest('hex');
        if (!user) {
            return res.json({
                success: false,
                message: '认证失败,用户名找不到'
            });
        } else if (user.hash_password === password) {
            var token = jwt.sign(user, 'whuteditor', {
                expiresIn: "30 days" // 设置过期时间
            });
            var tokenUser = new Token({
                token: token
            });

            tokenUser.set("nickname", req.body.name);

            tokenUser.save(function(err, token) {
                if (err) {
                    return res.json({
                        status: 120,
                        success: false,
                        message: "存储出错"
                    });
                }
                console.log(token);
            });
            return res.json({
                status: 100,
                success: true,
                message: 'Enjoy your token!',
                token: token
            });
            //res.end();
            //res.end();
        } else {
            return res.json({
                status: 007,
                success: false,
                message: '没有当前用户'
            });
        }
    });
});

module.exports = router;

错误:

Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
    at ServerResponse.header (/Users/guchenghao/Atom-code/project/editor/node_modules/express/lib/response.js:718:10)
    at ServerResponse.send (/Users/guchenghao/Atom-code/project/editor/node_modules/express/lib/response.js:163:12)
    at ServerResponse.json (/Users/guchenghao/Atom-code/project/editor/node_modules/express/lib/response.js:249:15)
    at ServerResponse.send (/Users/guchenghao/Atom-code/project/editor/node_modules/express/lib/response.js:151:21)
    at /Users/guchenghao/Atom-code/project/editor/routes/login.js:40:18
    at /Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/lib/document.js:1813:19
    at handleError (/Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:40:22)
    at next_ (/Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:75:26)
    at fnWrapper (/Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:186:18)
    at /Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/lib/model.js:287:15
    at /Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/lib/model.js:188:14
    at /Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/lib/model.js:132:9
    at /Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/node_modules/mongodb/lib/collection.js:491:20
    at /Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/node_modules/mongodb/lib/collection.js:604:14
    at handleCallback (/Users/guchenghao/Atom-code/project/editor/node_modules/mongoose/node_modules/mongodb/lib/utils.js:96:12)

npm ERR! Darwin 15.3.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v4.3.0
npm ERR! npm  v2.14.12
npm ERR! code ELIFECYCLE
npm ERR! editor@0.0.0 start: `node ./bin/www`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the editor@0.0.0 start script 'node ./bin/www'.
npm ERR! This is most likely a problem with the editor package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     node ./bin/www
npm ERR! You can get their info via:
npm ERR!     npm owner ls editor
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/guchenghao/Atom-code/project/editor/npm-debug.log

2 个答案:

答案 0 :(得分:1)

在致电res.json之前,您可以使用res.headersSent检查您的标头是否已发送。如果已发送,只需致电next()

<强>更新 您在.save函数中有竞争条件。

var crypto = require('crypto');
var express = require('express');
var jwt = require('jsonwebtoken');
var router = express.Router();
var User = require('../modules/user');
var Token = require('../modules/token');

router.get('/', function(req, res,next) {
   res.render('login', {
       title: '登录界面'
   });
   //next(); remove this next();
});

router.post('/', function(req, res) {
    User.findOne({
        tel: req.body.tel,
    })
    .exec(function(err, user) {
        var md5 = crypto.createHash('md5'),
            password = md5.update(req.body.password)
            .digest('hex');
        if (!user) {
            return res.json({
                success: false,
                message: '认证失败,用户名找不到'
            });
        } else if (user.hash_password === password) {
            var token = jwt.sign(user, 'whuteditor', {
                expiresIn: "30 days" // 设置过期时间
            });
            var tokenUser = new Token({
                token: token
            });

            tokenUser.set("nickname", req.body.name);

            tokenUser.save(function(err, token) {
                if (err) {
                    return res.json({
                        status: 120,
                        success: false,
                        message: "存储出错"
                    });
                } else {
                    console.log(token);
                    return res.json({
                        status: 100,
                        success: true,
                        message: 'Enjoy your token!',
                        token: token
                    });
                }

            });

            //res.end();
            //res.end();
        } else {
            return res.json({
                status: 007,
                success: false,
                message: '没有当前用户'
            });
        }
    });
});

module.exports = router;

答案 1 :(得分:-1)

如果您已经向res写了一些内容,然后某些代码(很可能是链中的下一个中间件)尝试编写标题,就会发生此错误。

您的问题的解决方案可能是:如果您已向next()写了一些内容,请移除res

router.get('/', function(req, res,next) {
   res.render('login', {
       title: '登录界面'
   });

   //Remove this next(), this causes next middleware to be executed.
   //next();
});

此外,这是另一个问题,在下面的代码中

     tokenUser.save(function(err, token) {
                if (err) {
                    return res.json({
                        status: 120,
                        success: false,
                        message: "存储出错"
                    });
                }
                console.log(token);
            });

            return res.json({
                status: 100,
                success: true,
                message: 'Enjoy your token!',
                token: token
            });

您首先发送回复

return res.json({
                status: 100,
                success: true,
                message: 'Enjoy your token!',
                token: token
            });

就在你之前你正在执行tokenUser.save,它在回调中再次发送响应!这就是你收到错误的原因。

你应该重写你的代码,如:

tokenUser.save(function(err, token) {
  if (err) {
    return res.json({
      status: 120,
      success: false,
      message: "存储出错"
    });
  } else {
    return res.json({
      status: 100,
      success: true,
      message: 'Enjoy your token!',
      token: token
    });
  }
  console.log(token);
});

希望这有帮助!