2013-11-04 59 views
2

我對express.urlencoded()中間件生成的request.body有點問題。在某些情況下,在request.body對象的末尾添加__proto__和比它不能直接用於啓動moongose模型,像這樣var user = new User(req.body)Express.js請求正文__proto__

作爲一個例子,我將使用node-express-mongoose-demo庫。所有形式的工作得很好,但app.post('/users', users.create)臨危req.body「污染」與__proto__

預先感謝任何幫助

回答

0

嗯,這很有趣。 __proto__是一些javascript實現(包括node/v8)中所有對象的特殊/自動/內部屬性。雖然我沒有見過貓鼬做這種事。將傳遞給模型構造函數的屬性轉換爲模型/文檔實例is here的代碼。雖然我沒有看到任何可疑的東西。

你知道究竟發生了哪種情況,你確定它是urlencoded嗎?當您嘗試保存已被此「污染」的用戶時會發生什麼?通常貓鼬會忽略模式中未定義的字段,那麼會發生什麼?

你應該能夠(也許?)用下面的中間件解決這個問題,但我很好奇,要真正隔離和理解根本原因。下劃線/ 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__

+0

這種解決方法可以像以下那樣重新創建正文對象:'var fields = Object.create(req.body)'但是您是否真的知道爲什麼有時會添加__proto__並且有時不會? –

+0

我在創建對象時沒有看到任何奇怪的東西,所以我不確定'req.body.proto'來自哪裏,但是您的應用中可能還有其他一些中間件是在污染它? https://github.com/senchalabs/connect/blob/7edb875a9f305e38f4d960fa46ac674038241892/lib/middleware/urlencoded.js#L47 –

+0

我發現'__proto__'沒有添加,當窗體有屬性'enctype =「multipart/form-數據「'。所以多部分中間件不會產生額外的密鑰。 –

2

看來問題來自urlencoded中間件,它包含在Express 3中。

可能的解決方案不是使用Express bodyParser,而是使用body-parser模塊。

而不是

app.use(express.urlencoded()) 

你可以寫

var bodyparser = require('body-parser') 

.......... 

app.use(bodyparser.urlencoded()) 

這個問題似乎來自qs模塊(由express 3模塊使用的版本)。它強制在其構建的對象上添加一個__proto__。最後的版本沒有這個問題。