1. 程式人生 > >Nodejs學習筆記之從bodyParse來看app.use()

Nodejs學習筆記之從bodyParse來看app.use()

前言
最近一直在學習慕課網上的express+mongodb建站課程,老師用了很多模組,以前從未見過,因此慢慢看API文件,調程式碼,試圖把每一個框架都搞懂。
前一篇寫了express一些用法,這一篇也是接上文的,主要是提到了app.use()。
因為在本專案中,app.use()方法主要用在,app.use(bodyParser())

先貼程式碼

var express=require('express')
var bodyParser=require('body-parser')
var Movie=require('./models/movie')
var mongoose=require
('mongoose') var port=process.env.PORT||3000 var app=express() app.set('views','./views/pages') //設定檢視 app.set('view engine','jade') //設定引擎 app.use(bodyParser()) app.listen(port) console.log('service start at port'+port) //編寫路由 //addmovie page app.post('/admin/movie/new',function(res,req){ var id=req.body.movie._id var
movieObj=req.body.movie var _movie if(id!=='undefined'){ Movie.findById(id,function(err,movie){ if(err){ console.log(err) } _movie= _.extend(movie,movieObj) _movie.save(function(err,movie){ if(err){ console.log(err) } res.redirect('/movie/'
+movie._id) }) }) } else{ _movie=new Movie({ doctor:movieObj.doctor, tittle:movieObj.tittle, country:movieObj.country, language:movieObj.language, year:movieObj.year, poster:movieObj.poster, summary:movieObj.summary, flash:movieObj.flash }) _movie.save(function(err,movie){ if(err){ console.log(err) } res.redirect('/movie/'+movie._id) }) } })

先說bodyParse的使用

var bodyParser=require('body-parser')
app.use(bodyParser())

以前bodyParse是在express模組中,後來單獨出來了,所以必須要按照上面的先npm install body-parser,再require,再app.use()

express專案中通常使用body-parser進行post引數的解析,最常用的是其中的json和urlencoded的parser,可分別對以JSON格式的post引數和urlencoeded的post引數進行解析,均可獲得一個JSON化的req.body,如:

{
    "username": "user",
    "password": "pass"
}

body-parser還有一個raw parser,可以獲取一個buffer物件的req.body。

通過詳細閱讀body-parser的原始碼,可以知道,各個parser會對req headers及post引數進行一系列的判斷和處理,只有滿足條件的情況下才對post引數進行解析,解析之前,首先使用raw-body模組對req進行處理,其處理過程是將req作為一個readable stream進行處理,從而得到raw body內容,然後按具體的格式進行解析。

在express專案中,通常順序呼叫body-parser所提供的parser,這樣當一個parser無法滿足post引數解析條件時,還可以使用另一個parser進行解析(在某些特殊的請求中,有可能所有parser均無法解析)

app.use(bodyParser.raw);
app.use(bodyParser.json);
app.use(bodyParser.urlencoded({
    extended: false
});

但body-parser的各個parser在解析的過程中,若對滿足解析條件的post引數進行了解析,req作為一個stream物件,已經被消耗,無法再使用另一個parser對post引數解析,也即post引數只能被第一個滿足解析條件的parser進行解析。因此即使先後呼叫raw、json、urlencoded這三個parser,也只能得到一個body,具體格式由各parser的呼叫次序及post引數滿足的解析條件決定。JSON化的body和raw body如同魚與熊掌,二者不可得兼。