Express.js请求正文__proto__
express.urlencoded()中间件生成的request.body有点问题。 在某些情况下,它会在request.body对象的末尾添加__proto__
,并且不能直接用来启动moongose模型,如var user = new User(req.body)
作为一个例子,我将使用node-express-mongoose-demo存储库。 所有表单都可以正常工作,但是app.post('/users', users.create)
用__proto__
收到了req.body“污染”
在此先感谢您的帮助
看来,这个问题来自urlencoded
中间件, Express 3
包含的中间件。
一个可能的解决scheme是不使用Express bodyParser,而是使用body-parser
模块。
代替
app.use(express.urlencoded())
你可以写
var bodyparser = require('body-parser') .......... app.use(bodyparser.urlencoded())
问题似乎来自qs
模块( express 3
模块使用的版本)。 它强制在构build的对象上添加__proto__
。 最后的版本没有这个问题。
嗯,这很有趣。 __proto__
是一些javascript实现(包括node / v8)中所有对象的特殊/自动/内部属性。 我没有看到mongoose做这种types的事情。 将传递给模型构造函数的属性转换为模型/文档实例的代码就在这里 。 虽然我没有看到任何可疑的东西。
你知道究竟发生了哪些情况,你确定这是做urlencoded
吗? 当你试图保存一个被这个“污染”的用户时会发生什么? 通常mongoose会忽略模式中没有定义的字段,那么会发生什么?
你应该可以(也许?)用下面的中间件解决这个问题,但是我很好奇,要真正隔离和理解根本原因。 下划线/ 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__
。