如何使用不同的本地语言重新渲染ejs视图(发送后无法设置标头)

问题描述 投票:0回答:1

我仍然是一个node.js初学者,所以如果我在这里缺少一些基本的知识,请原谅。

因此,我正在使用node.js(express,mongoose,ejs)制作一个注册/登录系统,我想在用户提交登录表单时显示加载的gif,并将用户重定向到“ example.com/密码验证后(bcrypt)。

我当前的login.ejs代码是:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet">
    <title>Login</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
    <link rel="stylesheet" href="/styles/login.css">
</head>
<body>
    <div class="signup-form">
        <form action="/login" class="container-fluid" method="post">
            <% if (locals.loading == true) { %>
                <div class="form-group">
                    <img src="/images/spinner.gif" alt="Loading..." class="center-block">
                </div>
            <% } else { %>
                <h2>Login</h2>
                <p class="hint-text">Fast and reliable</p>
                <div class="form-group">
                    <input type="email" class="form-control" name="email" placeholder="Email" required>
                </div>
                <div class="form-group">
                    <input type="password" class="form-control" name="password" placeholder="Password" required aria-autocomplete="list">
                </div>
                <div class="form-group">
                    <input type="submit" class="btn btn-success btn-lg btn-block">
                </div>
            <% } %>
        </form>
        <div class="text-center">Don't have an account? <a href="/register">Register</a></div>
    </div>
</body>
</html> 

我的登录控制器是:

const User = require('../models/user')
const bcrypt = require('bcryptjs')

exports.render_view = (req, res) => {
    res.render('login', {loading: false})
}

exports.login_user = async (req, res) => {
    res.render('login', {loading: true})
    const user = {
        email: req.body.email,
        password: req.body.password
    }
    const foundUser = await User.findOne({ email: user.email });
    if (foundUser) {
        bcrypt.compare(user.password, foundUser.password)
            .then((result) => {
                if (result) res.redirect('/dashboard')
                else res.redirect('/login')
            })
            .catch((err) => {console.log('Exception thrown\n', err)});
    } else {
        console.log('User not found')
    }
} 

路线:

const express = require('express')
const router = express.Router()

const login_controller = require('../controllers/login')

router.get('/', login_controller.render_view)

router.post('/', login_controller.login_user)

module.exports = router; 

由于某些原因,当我尝试登录时显示错误消息:

Exception thrown
Error: Can't set headers after they are sent.
    at validateHeader (_http_outgoing.js:491:11)
    at ServerResponse.setHeader (_http_outgoing.js:498:3)
    at ServerResponse.header (.../node_modules/express/lib/response.js:771:10)
    at ServerResponse.location (.../node_modules/express/lib/response.js:888:15)
    at ServerResponse.redirect (.../node_modules/express/lib/response.js:926:18)
    at bcrypt.compare.then (.../controllers/login.js:19:26)
    at <anonymous> 
javascript node.js express mongoose ejs
1个回答
0
投票

由于您没有向我提供更多详细信息,所以我只能根据您发送的信息来猜测问题,希望对您有所帮助。

您报告的错误,即Error: Can't set headers after they are sent.在尝试两次渲染页面或类似现象时很常见。

[从现在开始我假设您已经注册了用户(即User.findOne({ email: user.email })将返回某些内容),而您只想登录,这意味着您应该输入if (result) res.redirect('/dashboard')条件语句。

此外,由于用户可以看到您的表单,我相信您应该有类似的内容:router.get("/login"),它将为您提供EJS表单给用户,一旦用户提交,就应该转到router.post("/login"),根据<form action="/login" class="container-fluid" method="post">,应该是您在问题上提供的控制器,根据我的推理,这意味着您应删除该行 res.render('login', {loading: true}),并在没有的情况下将其放置在一个router.get,沿线的东西

router.get ("/login"){
 res.render('login', {loading: true})
}

登录EJS templace是您在问题中提供的内容。我不确定这会带来什么好处,因为EJS是静态的,而不是Angular,这意味着很可能您提交后就不会看到旋转的内容。

PS。请经验丰富的人告诉我说对了!我也是初学者!只是想帮助!

© www.soinside.com 2019 - 2024. All rights reserved.