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 ! :)


6 回复

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()。这可以避免在渲染视图时仍然继续处理请求,从而导致浏览器一直处于加载状态或无法正常响应其他链接的问题。

通过这种方式,你可以确保在用户未登录的情况下显示相应的通知页面,并且不会再执行不必要的操作。

回到顶部