我知道这个问题已经被问了5年了,但实际上昨天我也遇到了同样的问题。
我有好消息要分享 - 看起来 mongoose 5.3.9 实际上解决了这个问题。您可以使用包含__proto__
的对象创建新模型。不过不确定这是否会在未来持续存在。
此外,可以升级qs模块以解决此问题。
用于测试的代码:
let newCustomer = Object.create(null);
newCustomer.name = 'new test customer';
newCustomer.__proto__ = Object.prototype;
console.log(newCustomer);
Customer.create(newCustomer, function(err, created) {
console.log('err:', err, 'created:', created);
})
更多细节:
proto存在问题,因为qs模块使用以下方式创建新对象:
Object.create(null)
然后当调用restoreProto
时,它会尝试修复对象的原型:
obj.__proto__ = Object.prototype
而__proto__
最终成为对象的可见属性:
let obj = Object.create(null);
obj.__proto__ = Object.prototype;
console.log(Object.keys(obj));
// [ '__proto__' ]
如果使用
{}
或者
Object.create(Object)
创建新对象,那么即使以相同的方式分配,
__proto__
也不会出现在键枚举中。
let obj = {};
obj.__proto__ = Object.prototype;
console.log(Object.keys(obj));
// []
有趣的事实是 - 这种行为随着时间的推移而改变。在节点v0.10.28中,这两个代码片段(使用var而不是let ;))都会产生空数组。
另一个有趣的事情是,较新版本的qs模块以不同的方式创建对象,因此不再引起此问题。
var fields = Object.create(req.body)
,但您是否真的知道为什么有时会添加__proto__,有时不会? - Michał Zbytniewskireq.body.proto
是从哪里来的,但也许你应用程序中的其他一些中间件正在污染它? https://github.com/senchalabs/connect/blob/7edb875a9f305e38f4d960fa46ac674038241892/lib/middleware/urlencoded.js#L47 - Peter Lyonsenctype="multipart/form-data"
时,__proto__
不会被添加。因此,多部分中间件不会生成额外的键。 - Michał ZbytniewskiTypeError:Cannot read property 'ref' of undefined
,位于mongoose/lib/document.js line 449。 - Michał Zbytniewski