鍍金池/ 問(wèn)答/HTML/ express的res.json到底該如何正確返回?

express的res.json到底該如何正確返回?

在express開發(fā)中,經(jīng)常性碰到個(gè)問(wèn)題:

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

它老是報(bào)這個(gè)錯(cuò)誤:

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

請(qǐng)問(wèn)這要如何解決?加return都不行?要怎么操作才行的...

補(bǔ)充:這個(gè)接口的完整代碼:

router.post('/register', function (req, res, next) {
  console.log(req.body);
  if (req.body) {
    //時(shí)間函數(shù)
    function CurrentTime() {
      var now = new Date();

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

      var hh = now.getHours(); //時(shí)
      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);
    };

    //驗(yàn)證用戶名是否存在
    let userName = req.body.name;
    User.findOne({
      userName: userName
    }, function (userErr, userDoc) {
      console.log("userDoc err")
      if (userErr) {
        console.log("無(wú)此用戶:"+userName);
      } else {
        res.json({
          status: '1',
          msg: '查有此人,不可注冊(cè)',
          result: 'user-error'
        })
        return false;
      }
    })

    //驗(yàn)證兩次密碼是否相同并加密密碼
    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: '創(chuàng)建用戶成功!',
      result: 'success'
    });
  } else {
    console.log("req.body error")
    res.json({
      status: '0',
      msg: '拒絕空響!',
      result: 'error'
    })
    return false;
  }
})

返回的完整錯(cuò)誤:

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:\畢業(yè)設(shè)計(jì)\ConvenientCampus\server\views"
    at Function.render (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\application.js:580:17)
    at ServerResponse.render (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:971:7)
    at E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\server\app.js:89:7
    at Layer.handle_error (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\layer.js:71:5)
    at trim_prefix (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:315:13)
    at E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:284:7
    at Function.process_params (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:335:12)
    at next (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:275:10)
    at Layer.handle_error (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\layer.js:67:12)
    at trim_prefix (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:315:13)
    at E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:284:7
    at Function.process_params (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:335:12)
    at next (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:275:10)
    at E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:635:15
    at next (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\router\index.js:260:14)
    at next (E:\畢業(yè)設(shè)計(jì)\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:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:730:10)
    at ServerResponse.send (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:170:12)
    at ServerResponse.json (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_express@4.15.5@express\lib\response.js:256:15)
    at E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\server\routes\users.js:80:13
    at E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_mongoose@5.0.9@mongoose\lib\model.js:3930:16
    at Immediate.<anonymous> (E:\畢業(yè)設(shè)計(jì)\ConvenientCampus\node_modules\_mongoose@5.0.9@mongoose\lib\query.js:1514:14)
    at Immediate._onImmediate (E:\畢業(yè)設(shè)計(jì)\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)
回答
編輯回答
萌二代

你的return有問(wèn)題,在異步回調(diào)里的return不會(huì)阻止外部的代碼執(zhí)行,所以,最后的res,還是會(huì)執(zhí)行就回報(bào) Can't set headers after they are sent 這個(gè)錯(cuò)誤了

2017年7月7日 00:39
編輯回答
尛曖昧

對(duì)于同一個(gè) request 請(qǐng)求,你已經(jīng)在之前調(diào)用過(guò) res.end() 或者 res.json() 將此請(qǐng)求響應(yīng)完畢,所以不能再繼續(xù)響應(yīng)。

2017年6月5日 07:25
編輯回答
晚風(fēng)眠

這個(gè)錯(cuò)誤應(yīng)該是 請(qǐng)求已經(jīng)返回給客戶端了 之前的邏輯有么?

2018年8月27日 20:07