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

Javascript 在每次变量更改后更新res.locals?,javascript,node.js,mongodb,express,mongoose,Javascript,Node.js,Mongodb,Express,Mongoose,我正在尝试建立我自己的flash消息,但以一种更简单的方式。看起来是这样的: 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

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

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);
});
var errCode=0;
路由器使用(功能(req、res、next)
{
res.locals.errCode=errCode;
next();
});
router.post('/login',middleware.access,函数(req,res,next){
passport.authenticate('local',函数(err,user){
if(err){返回下一个(err);errCode=1;}
如果(!user){return res.redirect('/login');errCode=2;}
请求登录(用户、功能(错误){
if(err){返回下一个(err);errCode=1;}
返回res.redirect('/reguine/'+req.body.reguine);
});
})(req、res、next);

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

而且,您从未将
errorCode
设置为与
0
不同的值。因为在返回语句之前总是有一个返回语句,例如:

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) {
  // ...
})
然后,使用的代码在post的on之前执行,因此即使设置了
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);
});

使用全局变量在路由/中间件之间传递数据是一个非常糟糕的主意,因为您必须始终假设可能有两个请求同时命中您的服务器,然后
errorCode
将被一个请求覆盖,然后才能被另一个请求用于渲染。您必须将请求/响应/任务因变量与相应的对象一起存储。我不知道这一点。谢谢那么,如何轻松实现flash消息呢?您需要使用会话处理,将消息作为url参数通过重定向传递,或者根本不重定向,但使用给定的错误消息呈现
post
页面。如果你想处理所有的边缘案例,Flash消息根本不是一件容易的事情。我不想重定向。检查我尝试做的事情的示例。你能帮我做吗?我不知道怎么做,我想我需要这个技能。我看过你的代码,我提到了三种不同的解决方法。此外,您的代码不清楚,没有太多意义。无论如何,如果您想使用
errCode
而不进行任何重定向,那么为什么不编写
res.locals.errCode=1而不是
errCode=1?使用
res
对象是如何为同一请求在不同的中间件之间传递数据因此,我可以定义错误代码。我从ejs中得到:无法读取未定义的属性“errCode”。@AndreiDaniel您的ejs设置无法读取存储在
locals
中的值与您的问题完全不同。只有在演示如何设置和使用ejs渲染器时,才能告诉您问题所在。