我知道这个问题被问到现在已经 5 年了,但实际上我昨天遇到了同样的问题。
我有好消息要分享 - 看起来mongoose 5.3.9实际上解决了这个问题。您可以使用包含的对象创建新模型__proto__
。不过,不确定这是否会在未来持续存在。
另外,qs 模块也可以升级到最新版本来解决这个问题。
用于测试的代码:
// simulate object creation by express
let newCustomer = Object.create(null);
newCustomer.name = 'new test customer';
newCustomer.__proto__ = Object.prototype;
console.log(newCustomer); // { name: 'new test customer', __proto__: {} }
Customer.create(newCustomer, function(err, created) {
console.log('err:', err, 'created:', created);
// mongose 5.3.8: ValidationError: Customer validation failed
// mongose 5.3.9: new customer created
})
更多细节:
原型是有问题的,因为 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 模块以不同的方式创建对象,因此它不再导致此问题。