使用Node.js和connect-flash登录后显示用户名遇'req未定义'错误
解决connect-flash中req未定义错误并实现登录后显示用户名
问题描述
登录成功后想用connect-flash在主页显示用户名,但在app.post请求里的req.flash("user", req.body.username)代码处,出现了req is not defined的错误。之前在app.get请求里也碰到过类似错误,把app.use(flash)移到session中间件之后就解决了,现在求通俗的解释和解决办法。
相关代码
HTML模板代码
<p>Hello <%= username %></p> <div class="login"> <h1>Login</h1> <form action="/" method="post"> <label for="username"> <!-- font awesome icon --> <i class="fas fa-user"></i> </label> <input type="text" name="username" placeholder="Username" required /> <label for="password"> <i class="fas fa-lock"></i> </label> <input type="password" name="password" placeholder="Password" id="password" required /> <input type="submit" value="Login" /> </form> </div>
Node.js后端代码
const mysql = require("mysql"); const express = require("express"); const session = require("express-session"); const path = require("path"); var cookieParser = require("cookie-parser"); const flash = require("connect-flash"); const app = express(); const connection = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "nodelogin", }); app.use( session({ secret: "secret", resave: true, saveUninitialized: true, }) ); app.use(flash()); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(express.static(path.join(__dirname, "static"))); app.set("view engine", "ejs"); // http://localhost:3000/ app.get("/", function (request, response) { // Render login template const username = request.flash("user"); response.render("login", { username }); }); // http://localhost:3000/auth app.post("/", function (request, response) { // Capture the input fields let username = request.body.username; let password = request.body.password; // Ensure the input fields exists and are not empty if (username && password) { // Execute SQL query that'll select the account from the database based on the specified username and password connection.query( "SELECT * FROM accounts WHERE username = ? AND password = ?", [username, password], function (error, results, fields) { // If there is an issue with the query, output the error if (error) throw error; // If the account exists if (results.length > 0) { // Authenticate the user request.session.loggedin = true; request.session.username = username; // Redirect to home page req.flash("user", req.body.username); response.redirect("/"); console.log("succes"); } else { response.send("Incorrect Username and/or Password!"); } response.end(); } ); } else { response.send("Please enter Username and Password!"); response.end(); } }); app.listen(3000);
原因解释与解决方法
错误原因
你在post请求的回调函数里用了req这个变量,但这个回调的参数定义的是request和response——根本没声明req,所以JS找不到这个变量,自然报错。和之前app.get的问题完全不一样:之前是中间件顺序错了(flash依赖session,必须先挂载session再挂载flash),这次纯粹是变量名用错了。
解决步骤
统一变量名
把post请求回调的参数改成req和res(和行业常用写法一致,避免混淆),然后把函数里所有的request替换成req,response替换成res。这样req.flash就能正常找到变量了。修正后的post请求代码片段:
app.post("/", function (req, res) { let username = req.body.username; let password = req.body.password; if (username && password) { connection.query( "SELECT * FROM accounts WHERE username = ? AND password = ?", [username, password], function (error, results, fields) { if (error) throw error; if (results.length > 0) { req.session.loggedin = true; req.session.username = username; // 直接用已经定义好的username变量,不用重复取req.body req.flash("user", username); res.redirect("/"); console.log("success"); } else { res.send("Incorrect Username and/or Password!"); } res.end(); } ); } else { res.send("Please enter Username and Password!"); res.end(); } });优化显示逻辑(可选)
你已经把用户名存在req.session.username里了,其实可以不用flash直接从session取——flash是一次性消息,刷新页面就会消失,而session里的内容会一直存在(直到会话过期)。如果想让用户名持续显示,把app.get里的代码改成这样:app.get("/", function (req, res) { // 优先从session取用户名,没有再取flash消息 const username = req.session.username || req.flash("user"); res.render("login", { username }); });
内容的提问来源于stack exchange,提问作者user19551233
相关产品推荐
相关产品推荐

