Nodejs中res.render()和next(),不经意间犯得一个小错误
Nodejs中res.render()和next(),不经意间犯得一个小错误
直接进入主题吧,不去啰嗦了
我在我的routes.js中是这么写的app.get(’/stu/bacic’,auth.checkLogin,stuBasicInfo.getBasicInfo);
就是先验证是否登录,之后才跳转,原本这是一个很容易的事情,可我还是遇到一个小问题
思考片刻后就解决了。
####什么问题呢?####
我在auth.js中是这么写的:
exports.checkLogin = function(req,res,next){
if(!req.session.user){
res.render('notify',{
title:'登录提示',
error:'您还未登录,请登录!'
});
}
next();
}
聪明的你已经发现,这里有个很明显的错误,那么这个错误会有怎么样的表现呢?我调试的时候打开对应的url,发现浏览器
一直在进行加载的状态,我又点击其他的连接,毫无任何的反应,之后我又仔细的看了上面的那几行代码, 当时就觉的node在我点击对应的url时,代码执行到res.render(),之后又向下迅速执行next(),就这样,我的notify还没有渲染,就已经执行了next()。所以浏览器一直忙啊~~~,这时如果打开其他的url,是不成功的。 因为我在开发阶段,所以直接把res.render()全部注释了,这样就okay了,如果正式开发的话, 解决方法就是在res.render()前加一个return ! :)
Nodejs中res.render()和next(),不经意间犯得一个小错误
直接进入主题吧,不去啰嗦了。
我在routes.js
中是这么写的:
app.get('/stu/basic', auth.checkLogin, stuBasicInfo.getBasicInfo);
就是先验证是否登录,之后才跳转。原本这是一个很容易的事情,但我也遇到了一个小问题。
什么问题呢?
我在auth.js
中是这么写的:
exports.checkLogin = function(req, res, next) {
if (!req.session.user) {
res.render('notify', {
title: '登录提示',
error: '您还未登录,请登录!'
});
}
next();
}
聪明的你可能已经发现了这个问题。这个错误会导致什么后果呢?我在调试时打开对应的URL,发现浏览器一直在进行加载的状态。当我点击其他链接时,也没有任何反应。经过仔细检查,我发现当时代码执行到res.render()
后,紧接着就执行了next()
。这就导致了notify
页面还没有渲染出来,就已经执行了next()
。因此,浏览器一直在等待响应,而其他链接也无法正常加载。
具体来说,当用户未登录时,res.render()
会被调用以渲染一个通知页面。然而,next()
仍然被执行了,这意味着中间件链将继续处理请求,即使当前的响应尚未完成。这会导致一系列不可预料的行为,如页面加载停滞、其他请求无法响应等。
解决方案
在开发阶段,我直接注释掉了res.render()
,这样问题就解决了。但在正式开发中,应该使用以下方法来避免这种情况:
exports.checkLogin = function(req, res, next) {
if (!req.session.user) {
res.render('notify', {
title: '登录提示',
error: '您还未登录,请登录!'
});
return; // 添加这一行
}
next();
}
通过在res.render()
之后添加return
语句,可以确保在渲染响应后立即退出当前函数,从而防止next()
被调用。这样就能确保响应正确发送,并且不会影响后续的请求处理。
嗯嗯。这种少了 return 的小错误,在 if (err) {next(err)}
中也很容易出现。
嗯,是的。小错误不能再犯 :)
也可以使用if-else做法
这是为什么啊
在Node.js中使用Express框架时,res.render()
和 next()
的正确顺序非常重要。如果你不小心将 next()
放在了 res.render()
之后,会导致一些未预期的行为。具体来说,当 res.render()
被调用时,Express会开始渲染视图并发送响应给客户端。如果在 res.render()
之后还调用了 next()
,Express会认为你还想继续处理这个请求,并可能会导致重复渲染或其它未定义行为。
正确的做法是在 res.render()
之后立即返回,以确保不会执行后续的操作。以下是一个修复后的示例:
exports.checkLogin = function(req, res, next) {
if (!req.session.user) {
return res.render('notify', {
title: '登录提示',
error: '您还未登录,请登录!'
});
}
next();
};
在这个修正后的代码中,我们使用了 return
关键字来确保一旦调用 res.render()
后,函数立即退出,不会再执行 next()
。这可以避免在渲染视图时仍然继续处理请求,从而导致浏览器一直处于加载状态或无法正常响应其他链接的问题。
通过这种方式,你可以确保在用户未登录的情况下显示相应的通知页面,并且不会再执行不必要的操作。