Nodejs讨论:express-partials视图助手不能立即显示session数据的问题

Nodejs讨论:express-partials视图助手不能立即显示session数据的问题

刚发现一个问题,不知道谁有没有遇到过,就是在用express-partials的时候,当往session里面存入数据后render到页面的时候(我在页面显示该条session数据),并不能立刻显示出来,只有刷新一下才能显示。这会不会是该模块包的一个bug 代码很简单,如:

exports.reg = function (req, res) {
    req.session.info="reg";
    res.render('reg', { title:'注册页面' });
};
exports.login = function (req, res) {
    req.session.info="login";
    res.render('login', { title:'用户登录' });
};

app.js中app.configure里写有:

app.use(function (req, res, next) {
  
    res.locals({
        info:req.session.info,
    });
    next();
});

layout页面代码部分

...
信息<%= info%><br/>
<a href="/login">登入</a>
<a href="/reg">註冊</a>
...

然后当在页面来回切换点击按钮的时候,session信息显示的有问题,也就是当点击后刷新页面的话才是真实的session信息,(就好像页面先解析出来以后,session内才进入的信息似的)这个问题有办法解决吗?


4 回复

Nodejs讨论:express-partials视图助手不能立即显示session数据的问题

问题描述

最近在使用 express-partials 的过程中遇到了一个问题,即当向 session 中存储数据后,通过 res.render 渲染页面时,并不能立即显示出最新的 session 数据。必须刷新页面后才能看到更新后的数据。

示例代码

控制器代码

exports.reg = function (req, res) {
    req.session.info = "reg"; // 存储 session 数据
    res.render('reg', { title: '注册页面' });
};

exports.login = function (req, res) {
    req.session.info = "login"; // 存储 session 数据
    res.render('login', { title: '用户登录' });
};

中间件配置

app.use(function (req, res, next) {
    res.locals({
        info: req.session.info, // 将 session 数据注入到 locals 中
    });
    next();
});

布局页面代码

<!DOCTYPE html>
<html>
<head>
    <title><%= title %></title>
</head>
<body>
    信息<%= info %><br/>
    <a href="/login">登录</a>
    <a href="/reg">注册</a>
</body>
</html>

问题分析

上述代码中,每次请求处理完后,res.locals 会将 req.session.info 注入到视图模板中。但是,由于 express-partials 在渲染过程中可能存在一些延迟或缓存机制,导致页面首次加载时无法立即显示最新的 session 数据。

解决方案

为了解决这个问题,可以尝试以下几种方法:

  1. 确保每次请求都更新 session 数据: 确保每次请求处理完后都更新 session 数据,并且 res.locals 中也正确地注入了这些数据。

  2. 使用中间件确保数据更新: 可以添加一个中间件来确保在每次渲染之前都更新 locals 数据。

    app.use(function (req, res, next) {
        res.locals.info = req.session.info;
        next();
    });
    
  3. 手动刷新页面: 如果上述方法仍然无法解决问题,可以在客户端添加一些逻辑,例如在点击按钮后手动刷新页面,确保数据是最新的。

    <script>
        document.querySelector('a').addEventListener('click', function() {
            location.reload(); // 手动刷新页面
        });
    </script>
    

通过以上方法,应该能够解决 express-partials 视图助手不能立即显示 session 数据的问题。希望这些解决方案能帮助你更好地理解和处理这个问题。


问题最终找到原因了,app.use这个方法只有在请求达到时才执行一次,然后next去执行相应的控制跳转,这样一来,如果在控制跳转get方法里面给session赋值后并不会立即给res.locals,所以只有下次请求时才能得到真实的session。到底还是误解了app.use这个方法了,我把它当作了Struts2的那种拦截器模式了,以为进出控制跳转的get方法前后都会执行一次,原来不是这样。所以解决方法就是在get方法里面给req.session.info赋值的同时也给res.locals.info赋值

you get it

在使用 express-partialsexpress-session 的过程中,有时会遇到 session 数据不能立即显示的问题。这通常是由于中间件执行顺序或渲染时机导致的。

为了确保 session 数据能够在渲染时正确显示,可以做一些调整:

  1. 确保中间件顺序正确:确保在 app.use(expressSession(...)) 后定义 app.use 中间件。
  2. 更新渲染逻辑:确保每次渲染时都能获取最新的 session 数据。

以下是一些修改建议:

修改中间件

确保中间件在渲染之前能够访问到 session 数据:

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

const app = express();

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

// 确保这个中间件在路由处理程序之前
app.use((req, res, next) => {
    res.locals.info = req.session.info;
    next();
});

app.get('/login', (req, res) => {
    req.session.info = "login";
    res.render('login', { title: '用户登录' });
});

app.get('/reg', (req, res) => {
    req.session.info = "reg";
    res.render('reg', { title: '注册页面' });
});

// 其他配置
app.listen(3000);

模板代码

确保模板中的变量能够正确访问到 res.locals 中的数据:

<!-- layout.ejs -->
...
信息<%= info %><br/>
<a href="/login">登入</a>
<a href="/reg">注册</a>
...

路由处理

确保在每次渲染前设置 session 数据,并且使用 res.locals 将 session 数据传递给模板:

// 登录路由处理
app.get('/login', (req, res) => {
    req.session.info = "login";
    res.locals.info = req.session.info; // 手动设置 res.locals
    res.render('login', { title: '用户登录' });
});

// 注册路由处理
app.get('/reg', (req, res) => {
    req.session.info = "reg";
    res.locals.info = req.session.info; // 手动设置 res.locals
    res.render('reg', { title: '注册页面' });
});

通过这些修改,可以确保每次渲染时都能获取到最新的 session 数据。如果问题仍然存在,请检查是否有其他中间件或配置影响了 session 数据的处理。

回到顶部