You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

connect-flash无法将success_msg传递至res.locals问题求助

问题

尝试使用connect-flash设置闪存消息,但消息无法正常传递,res.locals.success_msg始终未被正确赋值。手动执行res.locals.success_msg = 'great';时页面可正常显示消息,但通过connect-flash方式失效。已安装所有依赖包,相关代码及日志如下:

Express 后端代码

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
require('dotenv').config(); // Load environment variables

const app = express();
const PORT = process.env.PORT || 3000; // Use the port from .env or default to 3000
const session = require('express-session');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo'); 
const mongoURI = process.env.MONGO_URI || 'mongodb://localhost:27017/sessionDB';
const flash = require('connect-flash');

// Connect to MongoDB with mongoose
mongoose.connect(mongoURI)
  .then(() => {
    console.log('Connected to MongoDB');
  })
  .catch((err) => {
    console.error('MongoDB connection error:', err);
  });

// Define middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(express.json());
app.use(flash());

// Session setup - generates a session cookie to use for logged in user
app.use(
    session({
        secret: process.env.COOKIE_SECRET || "er@(-_45rgD",
        resave: false,
        saveUninitialized: true, 
        cookie: { 
            secure: false, 
            maxAge : 5 * 60 * 1000, 
            sameSite: 'Strict' 
        }, 
        store: MongoStore.create({
            mongoUrl: mongoURI, 
            collectionName: 'sessions', 
            ttl: 14 * 24 * 60 * 60, 
        }),
    })
);

// Middleware to pass flash messages to views
app.use((req, res, next) => {
    console.log('flash sucess before setting locals:', req.flash('success_msg'));  // Logs flash messages before setting locals
    console.log('flash error before setting locals:', req.flash('error_msg'));  // Logs flash messages before setting locals
    res.locals.success_msg = req.flash('error_msg')[0] || ''; 
    res.locals.error_msg = req.flash('error_msg')[0]|| ''; 
    console.log('locals after setting:', res.locals);  // Logs locals object after setting flash messages
    next();
});

// Define routes

app.get('/flashsuccess', async (req, res) => {
    console.log('flashsuccess');
    req.flash('success_msg', 'This is a success message');
    res.redirect('/');
});

app.get('/flasherror', async (req, res) => {
    console.log('flasherror');
    req.flash('error_msg', 'This is an error message');
    res.redirect('/');
});


app.get('/', (req, res) => {
    console.log('Flash messages:', req.flash());  // Log flash messages directly
    console.log('Locals:', res.locals);  // Log locals directly
    res.render('index');  // Render with flash messages
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}`);
});

EJS 模板代码(index.ejs)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MongoDB</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
            <!-- Success Flash Message -->
            <% if (success_msg) { %>
                <div class="alert alert-success alert-dismissible fade show" role="alert">
                    <%= success_msg %>
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            <% } %>
    
            <!-- Error Flash Message -->
            <% if (error_msg) { %>
                <div class="alert alert-danger alert-dismissible fade show" role="alert">
                    <%= error_msg %>
                    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
                </div>
            <% } %>
    <a href="flashsuccess">set flash success message</a><br>
    <a href="flasherror">set flash error message</a><br>

    </div>
</body>
</html>

控制台输出日志

flashsuccess
flash sucess before setting locals: [ 'This is a success message' ]
flash error before setting locals: []
locals after setting: [Object: null prototype] { success_msg: '', error_msg: '' }
Flash messages: {}
Locals: [Object: null prototype] { success_msg: '', error_msg: '' }

问题定位与解决

核心错误点

  1. 中间件顺序错误:connect-flash依赖express-session,必须在session中间件之后加载,否则无法读取会话中的闪存消息。
  2. 闪存消息读取逻辑错误:
    • req.flash()调用会一次性清空对应类型的消息队列,日志中提前调用req.flash('success_msg')后,后续再调用就拿不到值。
    • 赋值res.locals.success_msg时错误使用req.flash('error_msg'),未对应正确的消息类型。
  3. 根路由多余调用:req.flash()不带参数会取出所有消息并清空,导致模板无法获取值。

修正后的代码

调整中间件顺序并修复闪存逻辑

// ... 其他代码不变

// 先加载session中间件,再加载flash
app.use(
    session({
        secret: process.env.COOKIE_SECRET || "er@(-_45rgD",
        resave: false,
        saveUninitialized: true, 
        cookie: { 
            secure: false, 
            maxAge : 5 * 60 * 1000, 
            sameSite: 'Strict' 
        }, 
        store: MongoStore.create({
            mongoUrl: mongoURI, 
            collectionName: 'sessions', 
            ttl: 14 * 24 * 60 * 60, 
        }),
    })
);
app.use(flash()); // 移到session中间件之后

// Middleware to pass flash messages to views
app.use((req, res, next) => {
    // 先将消息存入变量,避免重复调用req.flash()导致清空
    const successMsg = req.flash('success_msg');
    const errorMsg = req.flash('error_msg');
    console.log('flash success messages:', successMsg);
    console.log('flash error messages:', errorMsg);
    res.locals.success_msg = successMsg[0] || ''; 
    res.locals.error_msg = errorMsg[0] || ''; 
    console.log('locals after setting:', res.locals);
    next();
});

// ... 其他代码不变

// 根路由移除多余的req.flash()调用
app.get('/', (req, res) => {
    console.log('Locals:', res.locals);
    res.render('index');
});

验证效果

修正后,访问/flashsuccess跳转回首页会正常显示成功提示,访问/flasherror则显示错误提示,控制台日志中res.locals会正确赋值对应消息内容。

内容的提问来源于stack exchange,提问作者Patrik Horemans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:53:15