express的res.json到底该如何正确返回?

jsliang
  • 309

在express开发中,经常性碰到个问题:

    User.findOne({
      userName: userName
    }, function (userErr, userDoc) {
      if (userErr) {
        return res.json({
          status: '0',
          msg: userErr.message,
          result: '查无此人,可以注册'
        })
      } else {
        return res.json({
          status: '1',
          msg: '查有此人,不可注册',
          result: 'user-error'
        })
      }
    })

它老是报这个错误:

Error: Can't set headers after they are sent.

请问这要如何解决?加return都不行?要怎么操作才行的...

补充:这个接口的完整代码:

router.post('/register', function (req, res, next) {
  console.log(req.body);
  if (req.body) {
    //时间函数
    function CurrentTime() {
      var now = new Date();

      var year = now.getFullYear(); //年
      var month = now.getMonth() + 1; //月
      var day = now.getDate(); //日

      var hh = now.getHours(); //时
      var mm = now.getMinutes(); //分

      var clock = year + "-";
      // var clock = '';

      if (month < 10)
        clock += "0";

      clock += month + "-";

      if (day < 10)
        clock += "0";

      clock += day + " ";

      if (hh < 10)
        clock += "0";

      clock += hh + ":";
      if (mm < 10) clock += '0';
      clock += mm;
      return (clock);
    };

    //验证用户名是否存在
    let userName = req.body.name;
    User.findOne({
      userName: userName
    }, function (userErr, userDoc) {
      console.log("userDoc err")
      if (userErr) {
        console.log("无此用户:"+userName);
      } else {
        res.json({
          status: '1',
          msg: '查有此人,不可注册',
          result: 'user-error'
        })
        return false;
      }
    })

    //验证两次密码是否相同并加密密码
    let userPassword = req.body.pass;
    let userCheckPassword = req.body.checkPass;
    if (userPassword == userCheckPassword) {
      //生成口令的散列值
      let md5 = crypto.createHash('md5'); //crypto模块功能是加密并生成各种散列,此处所示为MD5方式加密
      let password = md5.update(userPassword).digest('hex'); //加密后的密码
    } else {
      console.log("password err")
      res.json({
        status: '0',
        msg: '密码不一致!',
        result: 'password-error'
      });
      return false;
    }
    console.log(password);

    let param = {
      userCreatetime: CurrentTime(),
      userName: userName,
      userPassword: password,
      userHostelArea: req.body.hostelArea,
      userHostelAddress: req.body.hostelAddress,
      userSex: req.body.sex,
      userQQ: req.body.qq,
      userState: "1"
    };
    User.create(param);
    res.json({
      status: "1",
      msg: '创建用户成功!',
      result: 'success'
    });
  } else {
    console.log("req.body error")
    res.json({
      status: '0',
      msg: '拒绝空响!',
      result: 'error'
    })
    return false;
  }
})

返回的完整错误:

GET /users/setSessionStorage 304 8.845 ms - -
GET /hostels 304 41.645 ms - -
{ name: '剑寒秋',
  pass: '123456',
  checkPass: '123456',
  hostelArea: '绿杨楼',
  hostelAddress: 'R413',
  sex: '男',
  qq: '123456' }
POST /users/register 500 26.365 ms - 2258
Error: Failed to lookup view "error" in views directory "E:\毕业设计\ConvenientCampus\server\views"
    at Function.render (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\application.js:580:17)
    at ServerResponse.render (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:971:7)
    at E:\毕业设计\ConvenientCampus\server\app.js:89:7
    at Layer.handle_error (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\layer.js:71:5)
    at trim_prefix (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:315:13)
    at E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:284:7
    at Function.process_params (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:335:12)
    at next (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:275:10)
    at Layer.handle_error (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\layer.js:67:12)
    at trim_prefix (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:315:13)
    at E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:284:7
    at Function.process_params (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:335:12)
    at next (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:275:10)
    at E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:635:15
    at next (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:260:14)
    at next (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\route.js:127:14)
userDoc err
events.js:183
      throw er; // Unhandled 'error' event
      ^

Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:494:11)
    at ServerResponse.setHeader (_http_outgoing.js:501:3)
    at ServerResponse.header (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:730:10)
    at ServerResponse.send (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:170:12)
    at ServerResponse.json (E:\毕业设计\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:256:15)
    at E:\毕业设计\ConvenientCampus\server\routes\users.js:80:13
    at E:\毕业设计\ConvenientCampus\node_modules\_mongoose@5.0.9@mongoose\lib\model.js:3930:16
    at Immediate.<anonymous> (E:\毕业设计\ConvenientCampus\node_modules\_mongoose@5.0.9@mongoose\lib\query.js:1514:14)
    at Immediate._onImmediate (E:\毕业设计\ConvenientCampus\node_modules\_mquery@3.0.0@mquery\lib\utils.js:119:16)
    at runCallback (timers.js:789:20)
    at tryOnImmediate (timers.js:751:5)
    at processImmediate [as _immediateCallback] (timers.js:722:5)
回复
阅读 5.4k
3 个回答
✓ 已被采纳

这个错误应该是 请求已经返回给客户端了 之前的逻辑有么?

对于同一个 request 请求,你已经在之前调用过 res.end() 或者 res.json() 将此请求响应完毕,所以不能再继续响应。

你的return有问题,在异步回调里的return不会阻止外部的代码执行,所以,最后的res,还是会执行就回报 Can't set headers after they are sent 这个错误了

宣传栏