快递.js请求正文__proto__
Express.js request body __proto__
我对 express.urlencoded() 中间件生成的 request.body 有一点问题。在某些情况下,它会在request.body对象的末尾添加__proto__
,而不是像这样直接用于启动moongose模型var user = new User(req.body)
作为一个例子,我将使用node-express-mongoose-demo存储库。所有形式都很好用,但app.post('/users', users.create)
会收到 req.body 被__proto__
"污染"
提前感谢您的任何帮助
问题似乎来自urlencoded
中间件,即包含在Express 3
中的中间件。
一个可能的解决方案不是使用 Express bodyParser,而是使用 body-parser
模块。
而不是
app.use(express.urlencoded())
你可以写
var bodyparser = require('body-parser')
..........
app.use(bodyparser.urlencoded())
问题似乎来自qs
模块(express 3
模块使用的版本)。它强制在其构建的对象上添加__proto__
。最新版本没有此问题。
嗯,这很有趣。 __proto__
是某些JavaScript实现(包括node/v8)中所有对象的特殊/自动/内部属性。不过,我还没有见过猫鼬做这种事情。此处提供了将传递给模型构造函数的属性转换为模型/文档实例的代码。不过,我没有看到任何可疑的东西。
您是否确切地知道这种情况会发生,并且您确定urlencoded
这样做吗?当您尝试保存被此"污染"的用户时会发生什么?通常猫鼬只会忽略架构中未定义的字段,那么会发生什么?
您应该能够(也许?)使用如下所示的中间件解决此问题,但我很好奇真正隔离和了解根本原因。 Underscore/Lodash omit
在这里效果很好。
var _ = require('lodash');
function unpollute(req, res, next) {
req.body = _.omit(req.body, '__proto__');
next();
}
app.use(express.urlencoded());
app.use(unpollute);
然后,当您的路由处理程序运行时,req.body
将不会有__proto__
.
问已经 5 年了,但实际上我昨天遇到了同样的问题。
我有好消息要分享 - 看起来猫鼬 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模块以不同的方式创建对象,因此不再导致此问题。
- javascript问题正文样式
- JQuery在单击正文时隐藏上下文菜单
- 我可以在网页正文中插入文本链接吗
- 未捕获的类型错误:无法设置属性'innerHTML'如果为null,则将脚本移动到正文不会;不起作用
- 正在尝试将标题标记添加到mailto链接,正文中包含URL
- 在外部(正文)单击时关闭弹出窗口
- 正文中未显示内容
- 将电子邮件正文导出到Google Sheets中的多个单元格中
- 如何将事件处理程序分配给proto.io开关
- 如何从应用于正文的css中排除特定的表单
- 使用 postman.setNextRequest() 在发送之前填充请求正文
- 阻止在单击和关闭覆盖菜单css时滚动正文
- 如何在不支持HTML字符的邮件正文中发送%签名
- IE9 XMLHTTPRequest请求正文不完整,但readyState=4 statuscode=200
- 我是否可以使用 Angular 将鼠标向上事件绑定到文档正文
- 类型错误:无法读取开机自检后未定义的属性“正文”(平均值)
- HTML 框架 - 防止引导弹出窗口在用户单击正文时消失
- 使用 switch 语句更改页面正文
- 设置正文高度宽度 CSS 表达式
- 在IE8和其他带有javascript的浏览器中获取正文类的标准解决方案是什么