【问题标题】:What can be a better way to handle sending response from controller in nodejs project?在nodejs项目中处理控制器发送响应的更好方法是什么?
【发布时间】:2018-01-13 21:46:04
【问题描述】:

rooms.js -> 房间端点的控制器类

router.get('/:roomid/fight/verify', function(req, res) {
      roomModel.authenticateUserForFight(req.params.roomid, req.query.otp, res);
    });

roomModel -> 房间的模型类

//authenticate user based on otp provided on client side
exports.authenticateUserForFight = function(roomid, otp, res) {
  db.query('select * from room where roomid=?', [roomid], function(error, rows) {
    if (rows.length == 0) {
      console.log("otp does not exist in db for room:" + roomid);
    } else if (rows.length == 1) {
      var otpInDb = rows[0].otp.toString();
      if (otp == otpInDb) {
        console.log("User is authorised");
        res.status(200);
        res.send("User is authorised");
      } else {
        console.log("User is unauthorised");
        res.status(401);
        res.send("User not authorised");
      }
    }
  });
}

这段代码工作正常,但是有没有更好的方法来向客户端发送响应,而不是将 res 对象传递给模型类并在那里设置状态和响应消息?我传递 res 对象的原因是因为在控制器中执行 res.status 和 res.send 会产生问题,因为 db 调用是异步的。建议一些更好的做法来处理这些情况。

【问题讨论】:

    标签: node.js asynchronous callback


    【解决方案1】:

    这是更新后的代码

    if (otp == otpInDb) {
            console.log("User is authorised");
            res.json({
                  status:200,
                  message:"user authorized"
            })
          } else {
            res.json({
                  status:401,
                  message:"user not authorized"
            })
          }
    

    最好用信封发送您的回复。我可以看到您正在使用String 之类的查询。使用sequelize之类的orm wrapper来防止SQL注入攻击

    【讨论】:

    • 目前我正在从模型文件返回响应。是否有可能以某种方式将其移至控制器类?你觉得从模特回来可以接受吗?
    • 根据我的喜好,我不从模型文件返回。因为模型定义了你的模式,它应该只有模式没有别的
    • 你能建议一些替代方法从控制器文件中返回它吗?我无法从控制器返回,因为 db.query 是异步调用并且不会等待并将控制权传递回控制器。
    【解决方案2】:

    你是对的。您不应传递 res 对象。如果函数可以退出的地方不止一个,那将是一场调试噩梦。后面的函数返回值,控制器响应状态要好得多。

    您可以简单地创建一个回调方法,该方法将在异步数据库查询完成后调用。像这样的

    router.get('/:roomid/fight/verify', function(req, res) {
          const callback = (status, message) => {
            res.status = status
            res.send(message);
          }
          roomModel.authenticateUserForFight(req.params.roomid, req.query.otp, callback);
        });
    

    主函数可以调用这个函数

    //authenticate user based on otp provided on client side
    exports.authenticateUserForFight = function(roomid, otp, callback) {
      db.query('select * from room where roomid=?', [roomid], function(error, rows) {
        if (rows.length == 0) {
          console.log("otp does not exist in db for room:" + roomid);
        } else if (rows.length == 1) {
          var otpInDb = rows[0].otp.toString();
          if (otp == otpInDb) {
            console.log("User is authorised");
            callback(200, 'user authorized');
          } else {
            console.log("User is unauthorised");
            callback(401, 'user not authorized');
    
          }
        }
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 2021-05-30
      • 2011-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多