Nodejs mongoose model里的session没反应,求救
Nodejs mongoose model里的session没反应,求救
各位大虾,小弟在使用session时出了一些问题
我确认过req.session是有作用的,但是放在mongoose model callback里面的session操作却没有反应,这是为什么??
以下是我的代码
signin: function(req, res){
req.session.test = “test1”; //可以作用
User.findOne({name: req.body.account}, function(err, user){
req.session.test = “test2”; //没有作用
});
res.cookie("blog", {
account: req.body.account,
password: req.body.password
}, {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30});
res.render('signin', {
title: 'signin'
});
}
Node.js Mongoose Model 里的 Session 没有反应,求救
各位大虾,小弟在使用 session 时遇到了一些问题。我确认过 req.session
是起作用的,但是在 mongoose model 的回调函数里面对 req.session
的操作却没有反应。这是为什么呢?
问题描述
我的代码如下:
signin: function(req, res) {
// 这行代码可以正常设置 session
req.session.test = "test1";
User.findOne({ name: req.body.account }, function(err, user) {
if (err) {
console.error(err);
return;
}
// 这行代码没有生效
req.session.test = "test2";
});
// 设置 cookie
res.cookie("blog", {
account: req.body.account,
password: req.body.password
}, { path: '/', maxAge: 1000 * 60 * 60 * 24 * 30 });
// 渲染视图
res.render('signin', {
title: 'signin'
});
}
原因分析
在 User.findOne
回调函数内部,Mongoose 异步查询数据库,而 res.render
和 res.cookie
是同步执行的。这意味着当 User.findOne
的回调被执行时,响应可能已经发送给客户端了(即 res.end()
已经被调用),这导致 req.session
的更改没有机会被保存到存储中。
解决方案
要解决这个问题,可以在 User.findOne
的回调函数中确保所有的 session 更新都已完成之后再渲染视图或发送响应。一种常见的做法是将这些操作封装在一个异步函数中,并等待所有操作完成后再进行下一步。
以下是改进后的代码:
signin: async function(req, res) {
// 设置 session
req.session.test = "test1";
try {
const user = await User.findOne({ name: req.body.account }).exec();
// 更新 session
req.session.test = "test2";
// 设置 cookie
res.cookie("blog", {
account: req.body.account,
password: req.body.password
}, { path: '/', maxAge: 1000 * 60 * 60 * 24 * 30 });
// 渲染视图
res.render('signin', {
title: 'signin'
});
} catch (err) {
console.error(err);
res.status(500).send('Internal Server Error');
}
}
在这个改进后的代码中,我们使用 async/await
来处理异步操作,确保在更新 session 之后再渲染视图和设置 cookie。这样可以保证所有的 session 更新都能成功保存到存储中。
哥哥,在你req.session.test = “test2”;之前你就调用了res.render(‘signin’, { title: ‘signin’ });哈哈,咋起作用啊,你这样试试 <pre><code>
User.findOne({name: req.body.account}, function(err, user){
req.session.test = "test2";
res.cookie("blog", {
account: req.body.account,
password: req.body.password
}, {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30});
res.render(‘signin’, {
title: ‘signin’
});
});
</pre></code>
多谢,终于解决了~
在Node.js中使用Mongoose模型时,如果你在findOne
回调函数内部修改了req.session
,可能会遇到会话不更新的问题。这是因为Mongoose的查询是异步执行的,而Express的会话中间件(如express-session
)默认情况下不会为每次请求重新加载会话数据。
解释
当你在User.findOne
的回调函数内部修改req.session
时,这个修改实际上是发生在异步回调中。然而,由于会话数据是在请求处理开始时加载到内存中的,并且通常在请求结束时才会被持久化,如果在异步操作完成之前请求已经结束,那么这个修改可能不会被保存。
解决方案
你可以使用touch
方法来手动确保会话数据被持久化。或者更简单地,在完成所有异步操作后,通过调用req.session.save()
来手动保存会话数据。
示例代码
const express = require('express');
const session = require('express-session');
const mongoose = require('mongoose');
const app = express();
app.use(session({
secret: 'your-secret-key',
resave: false,
saveUninitialized: true
}));
// 假设User模型已经定义好
const User = mongoose.model('User', new mongoose.Schema({ name: String }));
app.post('/signin', async (req, res) => {
req.session.test = "test1";
try {
const user = await User.findOne({ name: req.body.account });
if (user) {
req.session.test = "test2";
req.session.save((err) => {
if (err) console.error('Failed to save session:', err);
});
} else {
// 处理找不到用户的情况
}
} catch (error) {
console.error('Database error:', error);
}
res.cookie("blog", {
account: req.body.account,
password: req.body.password
}, { path: '/', maxAge: 1000 * 60 * 60 * 24 * 30 });
res.render('signin', {
title: 'signin'
});
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中,我们使用了async/await
语法来简化异步操作,并确保在修改会话数据后调用req.session.save()
方法来保存这些更改。