简体   繁体   English

如何在同一个 function 中使用 res.render 和 res.redirect

[英]How to use res.render and res.redirect in the same function

I am developing a widget for user login.我正在开发一个用于用户登录的小部件。 Basically, when they input valid account details I want it to render the same page (using handlebars) and state something like "Account successfully validated" and then 3 seconds later redirect the user.基本上,当他们输入有效的帐户详细信息时,我希望它呈现相同的页面(使用把手)和 state 类似“帐户已成功验证”,然后 3 秒后重定向用户。

This is the current code I have这是我当前的代码

router.post('/auth', (req, res, next) => {
    let username = req.body.username;
    let password = req.body.password;

    if (username && password) {
        connection.query('SELECT * FROM accounts WHERE username = ? AND password = ?', [username, password], (error, results, fields) => {
            if (results.length > 0) {
                req.session.loggedin = true;
                req.session.username = username;

                res.render('login.hbs', {
                    access: new hbs.SafeString('<p>Account successfully authenticated!</p>') // Display custom message
                });

                setTimeout(() => {
                    res.redirect('/admin'); // Redirect user
                }, 3000);

            } else {
                res.render('login.hbs', {
                    access: new hbs.SafeString('<p style="font-size: 1.2rem; margin-top: 2rem; color: red; font-weight:700;">Incorrect Username and/or Password!</p>')
                });
            }           
        });
    } else {
        res.render('login.hbs', {
            access: 'Please enter Username and Password'
        });
    }
});

However, whenever I try to do this I get the 'Cannot set headers after they have been sent to the client' Can someone please educate me on what the header system is and how I can fix this to get the desired result?但是,每当我尝试执行此操作时,我都会收到“在将标头发送到客户端后无法设置标头”,有人可以告诉我 header 系统是什么以及如何解决此问题以获得所需的结果吗?

Thank you!谢谢!

res.redirect() works by setting a Location HTTP header. res.redirect()通过设置Location HTTP header 来工作。 Those headers must be sent before any content is delivered to the client via the response body.这些标头必须在任何内容通过响应正文传递给客户端之前发送。

As an alternative to handling this delayed redirect client-side, you could use the non-standardised* Refresh header that allows to specify a delay in seconds before the redirect happens.作为处理此延迟重定向客户端的替代方法,您可以使用非标准化* Refresh header,它允许在重定向发生之前指定延迟(以秒为单位)。 Just add只需添加

res.set({'Refresh': '5; url=/admin'});

before you call res.render() .在调用res.render()之前。

* It was introduced by Netscape way back and since adopted by all major browsers, so despite never making it into the official HTTP standard, it's pretty safe to use it. *它是由 Netscape 早早引入的,并被所有主要浏览器采用,因此尽管从未将其纳入官方 HTTP 标准,但使用它非常安全。

And as a "bonus", if you were to solve it client-side, you would add作为“奖励”,如果你要在客户端解决它,你会添加

 <meta http-equiv="refresh" content="5; url=/admin"/>

to the header of your returned HTML markup, which does exactly the same.到您返回的 HTML 标记的 header ,其作用完全相同。

What's happening is.正在发生的事情是。 After you send a response, a particular request has been closed.发送响应后,特定请求已关闭。 The browser is no longer listening or connected to the same request.浏览器不再侦听或连接到同一请求。 So after sending a response, res.redirect() is throwing an error as the request is closed.因此,在发送响应后, res.redirect()会在请求关闭时引发错误。

What you can do is you can pass some flag or something similar, and handle redirection on the client-side.你可以做的是你可以传递一些标志或类似的东西,并在客户端处理重定向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM