在向用户呈现数据之前删除 JSON 内容/删除 JavaScript 对象属性

Delete JSON content before presenting data to the user / remove JavaScript object properties

本文关键字:删除 内容 JSON JavaScript 属性 对象 用户 数据      更新时间:2023-09-26

我有一个问题,我不太确定为什么我无法解决我的问题。

我有一个使用AngularJS,Node.JS和MongoDB(Mongoose(构建的SPA。现在在客户端上,我有一个注册新用户的表单。表单具有一个文本输入,该输入具有与其onblur事件(确切地说是ng-blur(关联的函数。该函数向后端发送Ajax/$http调用,以在提交表单之前检查用户名是否唯一。一切正常,这是我到目前为止的代码(请注意,我稍微修改了这个问题的代码(......

这是文本框,

<input type="text" name="displayName" id="displayName" ng-model="user.displayName" ng-blur="checkUserName(user)" />

这是我控制器中的模糊功能

this.userNameCheck = function(user){
        return $http({method: 'GET', url: '/api/users/displayName/' + user.displayName})
            .then(function(response) {
               if(response.data.length > 0){
                   user.userWarning = userWarning; // userWarning is a string/ var that is passed to the form
               }
            }, function(response) {
                console.log(response);
            });
    };

这是我的节点/猫鼬代码,它包含在不同的项目中:

exports.displayName = function (req, res, next, displayName) {
    User.find({displayName : displayName}).limit(1).exec(function (err, results) {
        if (err) return next(err);
        if (!results) return next(new Error('No user found'));
        res.jsonp(results || null);
    });
};

这一切都很棒,但是当我检查控制台时,我可以看到当我们有匹配项时,返回的结果对象包含哈希密码、盐等所有内容......我想防止这些在我的对象中返回。所以我修改了我的后端代码:

exports.displayName = function (req, res, next, displayName) {
    User.find({displayName : displayName}).limit(1).exec(function (err, results) {
        if (err) return next(err);
        if (!results) return next(new Error('No user found'));
        // new code
        if(results.length !== 0){
            var returnObj =  results[0];
             delete returnObj.hashed_password;
             delete returnObj.salt;
             delete returnObj._id;
            res.jsonp([returnObj] || null)
        }else{
            res.jsonp(results || null);
        }
    });
};

现在,当在 Firebug 中签入成功调用返回的内容(已找到匹配项(时,返回的对象仍然包含已删除的属性......我哪里出错了?

您正在尝试从 Mongoose 对象中删除,而不是实际存储中删除。最简单的更改是:

 var returnObj =  results[0].toJSON();
 delete returnObj.hashed_password;
 delete returnObj.salt;
 delete returnObj._id;

您也可以只select(文档(要包含/排除的字段。

我的猜测是,返回对象在原型链的上游具有这些属性,因此它们实际上不会被删除。

如果删除运算符成功,则会从对象中完全删除该属性。但是,如果对象的原型链上存在同名的属性,则该对象将从原型继承该属性。

~ MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete(

你可以用hasOwnProperty来检查这个理论,但是仅仅构建一个你想要的值的动态对象,或者限制从Mongo返回的值可能更安全?

换句话说,即时使用 JavaScript(类似(:

var returnObj =  results[0],
safeUserObj = {
   userName : returnObj["username"],
   email : returnObj["email"]
};
res.jsonp([safeUserObj]);

或者,您可以使用聚合框架的$match$project仅从 Mongo 返回所需的字段。 (下面的控制台样式代码,不确定您需要如何适应猫鼬(

db.users.aggregate([
{ $match : { displayName : displayName } },
{ $project : {
    displayName : 1,
    email : 1
  }
}
]);

编辑 :提到您可以使用 find 的项目参数来执行与我在底部解决方案中所做的相同的操作,而无需使用聚合框架。