Nodejs express 版本更新后遇到的问题 flash()

Nodejs express 版本更新后遇到的问题 flash()

首先发一个

原先的express 2.X中提供的API flash();

我找到一个关于修改的说明 req.flash() (just use sessions: req.session.messages = [‘foo’] or similar)

请问这个API原先的用途是什么?

4 回复

Node.js Express 版本更新后遇到的问题:flash()

原先的 flash() API

在早期版本(如Express 2.x)中,flash() 是一个非常方便的功能,用于临时存储消息。这些消息通常用于会话中的一次性通知,例如表单验证错误或成功消息。flash() 方法将消息存储在一个特殊的会话变量中,并且在下次请求时自动清除这些消息。

修改后的实现方式

在 Express 3.x 及更高版本中,flash() 功能被移除,开发者需要自己管理这些一次性消息。根据官方文档的建议,你可以使用会话来实现类似的功能。以下是一个简单的示例代码:

const express = require('express');
const session = require('express-session');

const app = express();

// 配置会话中间件
app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true
}));

// 自定义 flash 函数
function flash(req, message) {
    if (!Array.isArray(req.session.messages)) {
        req.session.messages = [];
    }
    req.session.messages.push(message);
}

// 自定义获取并清除消息的函数
function getMessages(req) {
    const messages = req.session.messages || [];
    delete req.session.messages;
    return messages;
}

// 示例路由
app.get('/login', (req, res) => {
    // 设置消息
    flash(req, '登录成功!');
    
    // 渲染页面时传递消息
    res.render('login', { messages: getMessages(req) });
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 配置会话中间件

    app.use(session({
        secret: 'your-secret-key',
        resave: false,
        saveUninitialized: true
    }));
    

    这里配置了会话中间件,确保每次请求都能访问到会话对象。

  2. 自定义 flash 函数

    function flash(req, message) {
        if (!Array.isArray(req.session.messages)) {
            req.session.messages = [];
        }
        req.session.messages.push(message);
    }
    

    flash 函数将消息推入 req.session.messages 数组中。

  3. 自定义获取并清除消息的函数

    function getMessages(req) {
        const messages = req.session.messages || [];
        delete req.session.messages;
        return messages;
    }
    

    getMessages 函数返回消息数组,并删除会话中的消息以确保它们只显示一次。

  4. 示例路由

    app.get('/login', (req, res) => {
        flash(req, '登录成功!');
        res.render('login', { messages: getMessages(req) });
    });
    

    在处理登录请求时,设置消息并将其传递给视图。

通过这种方式,你可以实现类似于 flash() 的功能,同时保持对会话数据的完全控制。


/**
 * Queue flash `msg` of the given `type`.
 *
 * Examples:
 *
 *      req.flash('info', 'email sent');
 *      req.flash('error', 'email delivery failed');
 *      req.flash('info', 'email re-sent');
 *      // => 2
 *
 *      req.flash('info');
 *      // => ['email sent', 'email re-sent']
 *
 *      req.flash('info');
 *      // => []
 *
 *      req.flash();
 *      // => { error: ['email delivery failed'], info: [] }
 *
 * Formatting:
 *
 * Flash notifications also support arbitrary formatting support.
 * For example you may pass variable arguments to `req.flash()`
 * and use the %s specifier to be replaced by the associated argument:
 *
 *     req.flash('info', 'email has been sent to %s.', userName);
 *
 * To add custom formatters use the `exports.flashFormatters` object.
 *
 * [@param](/user/param) {String} type
 * [@param](/user/param) {String} msg
 * [@return](/user/return) {Array|Object|Number}
 * [@api](/user/api) public
 */

req.flash = function(type, msg){
  if (this.session === undefined) throw Error('req.flash() requires sessions');
  var msgs = this.session.flash = this.session.flash || {};
  if (type && msg) {
    var i = 2
      , args = arguments
      , formatters = this.app.flashFormatters || {};
    formatters.__proto__ = flashFormatters;
    msg = utils.miniMarkdown(msg);
    msg = msg.replace(/%([a-zA-Z])/g, function(_, format){
      var formatter = formatters[format];
      if (formatter) return formatter(utils.escape(args[i++]));
    });
    return (msgs[type] = msgs[type] || []).push(msg);
  } else if (type) {
    var arr = msgs[type];
    delete msgs[type];
    return arr || [];
  } else {
    this.session.flash = {};
    return msgs;
  }
};

自己猜

Migrating from 2.x to 3.x

req.flash() (just use sessions: req.session.messages = [‘foo’] or similar) connect-flash can be used as middleware to provide req.flash()

需要安装 npm install connect-flash 在app.js中加入 var flash = require(‘connect-flash’); app.use(flash());

这样就能继续用 req.flash()

在 Express.js 的早期版本(如 2.x)中,req.flash() 是一个非常有用的中间件,用于处理一次性消息。这些消息通常用于显示用户反馈信息,例如成功或错误消息。

然而,在 Express 3.0 及更高版本中,req.flash() 已经被移除。现在推荐使用会话(session)来实现类似的功能。

req.flash() 的用途

req.flash() 用于存储一次性消息,这些消息只会在获取一次之后被删除。这非常适合用来显示表单提交后的反馈信息。

示例代码

假设你需要在用户登录时显示一条成功消息,可以使用以下方法:

使用会话存储一次性消息

const express = require('express');
const session = require('express-session');

const app = express();

app.use(session({
    secret: 'secret-key',
    resave: false,
    saveUninitialized: false
}));

app.post('/login', (req, res) => {
    // 模拟登录成功
    req.session.messages = [{ type: 'success', message: '登录成功!' }];
    res.redirect('/');
});

app.get('/', (req, res) => {
    const messages = req.session.messages || [];
    req.session.messages = null; // 清空消息以便下次使用
    res.send(`
        <h1>首页</h1>
        ${messages.map(m => `<div class="${m.type}">${m.message}</div>`).join('')}
    `);
});

app.listen(3000, () => console.log('Server running on port 3000'));

解释

  1. 会话配置

    • 我们使用了 express-session 中间件来配置会话。
  2. 登录路由

    • /login 路由中,我们模拟登录成功,并将消息存储到会话中。
  3. 首页路由

    • 在首页路由中,我们从会话中读取消息并显示它们。然后清空会话中的消息,以便下次使用。

这样,你可以通过会话来实现类似于 req.flash() 的功能。这种方式更灵活,也更符合现代 Express 的设计。

回到顶部