每次更改变量后更新res.locals吗?

时间:2018-12-16 10:24:10

标签: javascript node.js mongodb express mongoose

我正在尝试构建自己的Flash消息,但是以一种更简单的方式。看起来像这样:

var errCode = 0;

router.use(function(req, res, next)
{
    res.locals.errCode = errCode;
    next();
});

router.post('/login', middleware.access, function(req, res, next) {
    passport.authenticate('local', function(err, user) {
      if (err) { return next(err); errCode = 1;}
      if (!user) { return res.redirect('/login'); errCode = 2;}
      req.logIn(user, function(err) {
        if (err) { return next(err); errCode = 1;}
        return res.redirect('/regiune/' + req.body.regiune);
      });
    })(req, res, next);
  });

和EJS

<% if(errCode === 1){ %>
        <span class="login-error">err1</span><br/>
        <% } %>
        <% if(errCode === 2){ %>
            <span class="login-error">err2</span><br/>
        <% } %>
        <% if(errCode === 3){ %>
            <span class="login-error">err3</span><br/>
        <% } %>      

我的想法的问题是errCode传递的值为0,因为这是它最初的值。每当errCode更改时,是否有任何方法可以使res.locals.errCode更新?

1 个答案:

答案 0 :(得分:1)

使用全局变量在路由/中间件之间传递数据是一个非常糟糕的主意,因为您始终必须假设可能有两个请求同时到达您的服务器,然后errorCode将被一个请求覆盖,然后才能被另一个请求用于呈现。您必须将与请求/响应/任务相关的变量与相应的对象一起存储。

您永远不会将errorCode设置为与0不同的内容。因为您之前总是有一个return语句,例如:

return next(err); // the function is exit here before the next statement is executed
errCode = 1; // is never executed because this is unreachable code

中间件按其附加顺序执行,因此,如果您编写:

router.use(function(req, res, next) {
  // ...
})

router.post('/login', middleware.access, function(req, res, next) {
  // ...
})

然后,使用代码在帖子发布之前执行,因此即使设置了errCode,也将在设置res.locals.errCode = errCode之前执行errCode因此它将获得先前的errCode值。

所以您的代码必须看起来像这样:

router.post('/login', middleware.access, function(req, res, next) {
  passport.authenticate('local', function(err, user) {
    if (err) {
      res.locals.errCode = 1;
      return next(err);
    }
    if (!user) {
      res.locals.errCode = 2;
      // THIS WON'T WORK: because the `res.locals.errCode` will not 
      // survive the redirect you need to use sessions here or pass the 
      // error with the redirect
      return res.redirect('/login');
    }
    req.logIn(user, function(err) {
      if (err) {
        res.locals.errCode = 1;
        return next(err);
      }
      return res.redirect('/regiune/' + req.body.regiune);
    });
  })(req, res, next);
});