2014-09-10 62 views
3

我正在運行一個MongoDB,通過Mongoose訪問來存儲用戶記錄。我在服務器上也有下劃線。我有一個RESTful API和一個從數據庫返回一個集合(對象數組)的路由。我想將完整集合返回給客戶端,但是從每個對象中刪除密碼元素,以便不會發送到客戶端。在任何人說什麼之前,我將使用bcrypt在最終版本中使用salt並散列密碼:)underscore.js .keys和.omit不按預期工作

今天,我只在數據庫中有一個用戶'administrator'的條目。下面是我的路線代碼:

app.get('/users', function(req, res) { 
    User.find().sort({'userName': 'ascending'}).exec(function(err, data) { 
    _.each(data, function (element, index, list) { 
     console.log('userName=' + element.userName); 
     console.log('password=' + element.password); 
     delete element.password; 
     console.log('keys: ' + _.keys(element)); 
     console.log('password=' + element.password); 
     console.log(_.omit(element, 'password')); 
    }); 
    res.json(data); 
    }); 
}); 

我所得到的發送回瀏覽器:

[{"_id":"54058e6eb53dd60730295f59","modifiedOn":"2014-09-01T15:19:10.012Z", 
"userName":"administrator","password":"stackoverflow","role":"administrator", 
"__v":0,"createdBy":"54058e6eb53dd60730295f59","createdOn":"2014-09-01T15:19:10.004Z", 
"previousLogins":[],"accountIsLocked":false,"loginAttempts":0}] 

我們哪罰款,因爲res.json(data)聲明就發送原始data回瀏覽器 - 這不是問題。問題是delete(以及如果我使用.omit)似乎不適合我的收藏!正如你可以看到有很多的console.log進行調試,這裏是獲取輸出:

userName=administrator 
password=stackoverflow 
keys: $__,isNew,errors,_maxListeners,_doc,_pres,_posts,save,_events 
password=stackoverflow 
{ _id: 54058e6eb53dd60730295f59, 
    modifiedOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST), 
    userName: 'administrator', 
    password: 'stackoverflow', 
    role: 'administrator', 
    __v: 0, 
    createdBy: 54058e6eb53dd60730295f59, 
    createdOn: Mon Sep 01 2014 19:19:10 GMT+0400 (GST), 
    previousLogins: [], 
    accountIsLocked: false, 
    loginAttempts: 0 } 

_.keys輸出顯示鍵(?我從一個物體原型假設),我沒有看到,當我console.log(element)但沒有可通過element.key訪問的密鑰。

任何想法,爲什麼我看到這種行爲?

+0

這真的很奇怪。請參閱'_.keys'不應該訪問對象原型的屬性。 'console.log(element .__ proto __。constructor)'顯示什麼? – raina77ow 2014-09-10 14:04:04

+0

是的,我看起來也很奇怪! 'onsole.log(element .__ proto __。constructor)'輸出大量條目......這裏是一個pastebin鏈接:[link](http://pastebin.com/vUkFabHY) – 2014-09-10 14:58:53

回答

10

的問題是,data傳入exec回調函數實際上是一個Document對象 - 這可以被認爲是由貓鼬創造的Models的集合。這些對象有很多有用的方法,他們記得與db等的連接 - 但是你將無法將它們作爲普通對象來處理。

解決方案是指導貓鼬是你真正想要純JS對象與lean()查詢的結果是:

User.find().sort({'userName': 'ascending'}).lean().exec(function(err, data) { 
    // process the data 
}); 

另外,你應該能夠把每一個模型轉換爲普通物體.toObject()方法,然後過濾它:

var filtered = _.map(data, function(model) { 
    return _.omit(model.toObject(), 'password'); 
}); 
res.json(filtered); 

...但我寧願使用第一種方法。 )

+0

raina77ow,完美的工作,非常感謝! – 2014-09-10 15:50:36

+0

如果您可以使用ES6,那麼您可以更輕鬆地做到這一點。 let normalObject = {... data ['_ doc']} – Freddie 2018-02-16 11:58:19