express第三方中間件研究之bodyParser中間件


轉載至:http://www.cnblogs.com/lianer/p/5178693.html

接觸nodejs已有一段時間了,但最近才開始落實項目,於是使用express應用生成器生成了一個應用。開發過程中發現ajax提交的數據無法被express正確的解析,主要的情況是這樣的:

// 瀏覽器端post一個對象
$.ajax({
    url: "/save",
    type: "post",
    data: {
        name: "henry",
        age: 30,
        hobby: [ "sport", "coding" ]
    }
});

// express接收這個對象
router.post("/save", function (req, res, next) {
    console.log(req.body); // => { 'info[name]': 'henry','info[age]': '30','hobby[1]': 'sport','hobby[2]': 'coding' }
});

顯然這樣的解析結果是不能直接拿來用的,莫名其妙的一個坑,困了我許久。

bodyParser中間件

bodyParser中間件用來解析http請求體,是express默認使用的中間件之一。

使用express應用生成器生成一個網站,它默認已經使用了  bodyParser.json  與  bodyParser.urlencoded  的解析功能,除了這兩個,bodyParser還支持對text、raw的解析。

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

顧名思義,bodyParser.json是用來解析json數據格式的。bodyParser.urlencoded則是用來解析我們通常的form表單提交的數據,也就是請求頭中包含這樣的信息:  Content-Type: application/x-www-form-urlencoded 

常見的四種Content-Type類型:

  • application/x-www-form-urlencoded 常見的form提交
  • multipart/form-data 文件提交
  • application/json  提交json格式的數據
  • text/xml  提交xml格式的數據

詳細解讀 urlencoded

 bodyParser.urlencoded  模塊用於解析req.body的數據,解析成功后覆蓋原來的req.body,如果解析失敗則為 {}。該模塊有一個屬性extended,官方介紹如下:

The extended option allows to choose between parsing the URL-encoded data with the querystring library (when false) or the qs library (when true). Defaults to true, but using the default has been deprecated.

大致的意思就是:extended選項允許配置使用querystring(false)或qs(true)來解析數據,默認值是true,但這已經是不被贊成的了。

querystring就是nodejs內建的對象之一,用來字符串化對象或解析字符串。如

querystring.parse("name=henry&age=30") => { name: 'henry', age: '30' }

那么,既然querystring已經能完成對urlencode的解析了,為什么還需要qs?qs又是什么?

qs介紹

qs是一個querystring的庫,在qs的功能基礎上,還支持更多的功能並優化了一些安全性。比如,對象解析的支持:

// 內建對象 querystring
querystring.parse("info[name]=henry&info[age]=30&hobby[1]=sport&hobby[2]=coding") => 
  { 
    'info[name]': 'henry',
    'info[age]': '30',
    'hobby[1]': 'sport',
    'hobby[2]': 'coding'
  }

// 第三方插件 qs
qs.parse("info[name]=henry&info[age]=30&hobby[1]=sport&hobby[2]=coding") => 
  {
    info: {
      name: 'henry',
      age: '30'
    },
    hobby: [ 'sport', 'coding' ]
  }

可以看出,querystring並不能正確的解析復雜對象(多級嵌套),而qs卻可以做到。

但是qs也不是萬能的,對於多級嵌套的對象,qs只會解析5層嵌套,超出的部分會表現的跟本文頭部的那種情況一樣;對於數組,qs最大只會解析20個索引,超出的部分將會以鍵值對的形式解析。

作為一個中間件,qs必須要為性能考慮,才會有如此多的限制,express也默認使用qs來解析請求體。

理論上來說,form表單提交不會有多級嵌套的情況,而urlencoded本身也是form的內容類型,因此,bodyParser.urlencoded不支持多級嵌套也是很合理的設計。

那么,如果我們非要上傳一個十分復雜的對象,應該怎么辦?

解決方案

出現這個問題的根本原因是:我以form的形式去提交了一個json數據。

jquery默認的  content-Type  配置的是  application/x-www-form-urlencoded ,

因此更改ajax請求參數: contentType: "application/json" ,並將數據轉成json提交,問題就解決了。

// 瀏覽器端post一個對象
$.ajax({
    url: "/save",
    type: "post",
    contentType: "application/json",
    data: JSON.stringify({
        name: "henry",
        age: 30,
        hobby: [ "sport", "coding" ]
    })
});

// express接收這個對象
router.post("/save", function (req, res, next) {
    console.log(req.body); // => { name: 'henry', age: 30, hobby: [ 'sport', 'coding' ] }
});

參考資料

大多時候,我們只知道如何去使用,而不知道為什么這么用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM