为什么Express(Node.js)请求对象是只读的?

时间:2022-06-22 14:27:46

I'm using PassportJS but would like to have the user ID (_id) available to the front-end client. So I'm trying to splice in _id into the req.user.userInfo object:

我正在使用PassportJS,但希望前端客户端可以使用用户ID(_id)。所以我试图将_id拼接到req.user.userInfo对象中:

/** Create user */
exports.create = function (req, res, next) {
    var newUser = new User(req.body);
    newUser.provider = 'local';

    newUser.save(function(err) {
        if (err) {
            // Manually provide our own message for 'unique' validation errors, can't do it from schema
            if(err.errors.email.type === 'Value is not unique.') {
                err.errors.email.type = 'The specified email address is already in use.';
            }
            return res.json(400, err);
        }
        // Login after registration
        req.logIn(newUser, function(err) {
            if (err) return next(err);

            // Splice in _id
            req.user.userInfo['_id'] = req.user['_id'];
            console.log('newUser', req.user, req.user.userInfo);

            return res.json(req.user.userInfo);
        });
    });
};

However, the _id is not present in the returning JSON. Can objects be read-only?

但是,返回的JSON中不存在_id。对象可以是只读的吗?


Update: output of console.log:

更新:console.log的输出:

newUser { __v: 0,
  name: 'tom@myemail.com',
  hashedPassword: '$2a$10$r9ZL1JerqDko8zw72q5J5ONYZAWDpHDF1ROt0k35/1fRgfqNedGWG',
  salt: '$2a$10$r9ZL1JerqDko8zw72q5J5O',
  provider: 'local',
  email: 'tom@myemail.com',
  _id: 534552e8ecb0d69648000003,
  role: 'user' } { name: 'tom@myemail.com', role: 'user', provider: 'local' }

1 个解决方案

#1


3  

OK, 2nd theory: While req is a normal javascript object, req.user is a mongoose.js model instance. Mongoose has a few magical features, namely virtual properties and transforms during toObject and toJSON. I suspect maybe req.user.userInfo is a mongoose virtual, which is why modifications to it get ignored because mongoose regenerates the value every time req.user.userInfo is accessed.

好的,第二个理论:虽然req是一个普通的javascript对象,但req.user是一个mongoose.js模型实例。 Mongoose有一些神奇的功能,即在toObject和toJSON期间的虚拟属性和变换。我怀疑req.user.userInfo可能是一个mongoose虚拟,这就是为什么对它的修改会被忽略的原因,因为mongoose每次访问req.user.userInfo时都会重新生成值。

If that is true (my evidence is the __v property indicating mongoose, you can solve it by doing this:

如果这是真的(我的证据是指示猫鼬的__v属性,你可以通过这样做解决它:

        // Splice in _id
        var userInfo = req.user.userInfo;
        userInfo._id = req.user._id;
        console.log('newUser', req.user, userInfo);

        return res.json(userInfo);

And to your larger question, the req object is not read-only. There's some simpler bug going on in your code.

对于更大的问题,req对象不是只读的。您的代码中存在一些更简单的错误。

Aside: _id is a valid identifier so you should just use normal dot syntax, but square bracket syntax is equivalent.

旁白:_id是一个有效的标识符,因此您应该使用普通的点语法,但方括号语法是等效的。

#1


3  

OK, 2nd theory: While req is a normal javascript object, req.user is a mongoose.js model instance. Mongoose has a few magical features, namely virtual properties and transforms during toObject and toJSON. I suspect maybe req.user.userInfo is a mongoose virtual, which is why modifications to it get ignored because mongoose regenerates the value every time req.user.userInfo is accessed.

好的,第二个理论:虽然req是一个普通的javascript对象,但req.user是一个mongoose.js模型实例。 Mongoose有一些神奇的功能,即在toObject和toJSON期间的虚拟属性和变换。我怀疑req.user.userInfo可能是一个mongoose虚拟,这就是为什么对它的修改会被忽略的原因,因为mongoose每次访问req.user.userInfo时都会重新生成值。

If that is true (my evidence is the __v property indicating mongoose, you can solve it by doing this:

如果这是真的(我的证据是指示猫鼬的__v属性,你可以通过这样做解决它:

        // Splice in _id
        var userInfo = req.user.userInfo;
        userInfo._id = req.user._id;
        console.log('newUser', req.user, userInfo);

        return res.json(userInfo);

And to your larger question, the req object is not read-only. There's some simpler bug going on in your code.

对于更大的问题,req对象不是只读的。您的代码中存在一些更简单的错误。

Aside: _id is a valid identifier so you should just use normal dot syntax, but square bracket syntax is equivalent.

旁白:_id是一个有效的标识符,因此您应该使用普通的点语法,但方括号语法是等效的。