我正在尝试构建自己的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更新?
答案 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);
});