gpt4 book ai didi

node.js - 为什么会忘记对象的原型(prototype)?

转载 作者:行者123 更新时间:2023-12-03 12:11:39 25 4
gpt4 key购买 nike

介绍
所以我正在用 node.js、express、express-session 和 sequelize.js 构建一个网站。一旦用户登录,Sequelize 模型的实例 User被 build 。在我的用户登录路径( /auth/login )中,我有:

var user = (await User.findAll(
{where: {
username: username
}}))[0];
我在几行之后分配了 user到 session 。
req.session.user = user;
然后我可以通过简单地调用 save 来保留任何更改。 req.session.user的方法:
await req.session.user.save();
事实上,如果我接下来添加这一行:
console.log(Object.getPrototypeOf(req.session.user));
输出为 [object SequelizeInstance:User] .到现在为止还挺好。
这是问题
在另一条路线( /users/myaccount/edit-bio )中,我可以访问 req.session.user 的值.也就是说,输出
console.log(req.session.user.username);
seanletendre ,正如预期的那样。但现在当我打电话
await req.session.user.save();
我得到的只是错误消息:
UnhandledPromiseRejectionWarning: TypeError: req.session.user.save is not a function
“这很奇怪,”我想,“这不是同一个物体吗?”为了调查,我添加了以下行:
console.log(Object.getPrototypeOf(req.session.user));
就像我在登录 route 所做的那样。输出是什么?它是: [object Object] .所以似乎 req.session.user的原型(prototype)不知何故被遗忘。我不明白这怎么可能。
是否可以将原型(prototype)重新分配给普通对象?
嫌疑人A
根据对我的问题的评论,我怀疑在 session 管理器序列化 req.session 时原型(prototype)丢失了。 .看来,与我之前想的不同, req.session不指向完全相同的 session不同请求的对象。每次请求结束时,它都会序列化并存储 req.session .然后在接收到带有 cookie 的新请求时,将其指定为同一 session 的一部分, session对象是从 session 存储中获取的。
这就是我的 session 中间件的设置方式:
var session = require('express-session');
//
// yada, yada, yada
//
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {secure: true}
}));
所以令我惊讶的是,即使我使用的是默认存储 MemoryStore ,我的 session 仍然是序列化的。
我现在的问题是:如何在使用 MemoryStore 时防止 session 存储上的对象序列化?

最佳答案

express-session方法save()被对象 session 暴露进入request对象(docs),例如:

req.session.save(callback)
您的代码 req.session.user.save()错了,正确的方法是 req.session.save() , 差异。:
req.session.user.save();
-----------^^^^^
req.session.save()
方法 save()不是 Promise ,您必须通过回调等待保存结果:
req.session.user = user;
req.session.save(function(err) {
if( err ){
// session not saved
} else {
// session saved
}
})
您可以将其转换为 Promise (并等待它),以这种方式:
const saveSession = (req) => {
return new Promise((resolve, reject) => {
req.session.save(function(err) {
if( err ){
reject(err);
} else {
resolve(true);
}
});
});
};

req.session.user = user;
await saveSession(req);
方法 save()如果 session 数据已更改,则在 HTTP 响应结束时自动调用。因此,通常不需要调用此方法。
更新

I call req.session.user.save() because I want to save the SequelizeModel instance into my database.


快速 session 使用 JSON.stringify()用于将 session 序列化为字符串并存储到 session 存储中( more info)。 JSON.stringify()不理解函数,只存储属性。因此,您的 save()功能丧失。

关于node.js - 为什么会忘记对象的原型(prototype)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64853915/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com