淺談Express.js解析Post數(shù)據(jù)類型的正確姿勢(shì)
一、概念介紹
1、POST請(qǐng)求:HTTP/1.1
協(xié)議規(guī)定的 HTTP
請(qǐng)求方法有 OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT
這幾種。其中 POST
一般用來向服務(wù)端提交數(shù)據(jù)。
2、 Content-Type
: 是指 http/https
發(fā)送信息至服務(wù)器時(shí)的內(nèi)容編碼類型, Content-Type
用于表明發(fā)送數(shù)據(jù)流的類型,服務(wù)器根據(jù)編碼類型使用特定的解析方式,獲取數(shù)據(jù)流中的數(shù)據(jù)。四種常見的 POST
請(qǐng)求的 Content-Type
數(shù)據(jù)類型:
- application/x-www-form-urlencoded
- multipart/form-data
- application/json
- text/xml
3、 Express.js
: Express
是一個(gè)保持最小規(guī)模的靈活的 Node.js Web
應(yīng)用程序開發(fā)框架,為 Web
和移動(dòng)應(yīng)用程序提供一組強(qiáng)大的功能。
本文我們主要介紹 Post
請(qǐng)求的 4 種 Content-Type
數(shù)據(jù)類型,以及如何使用 Express
來對(duì)每種 Content-Type
類型進(jìn)行解析。已經(jīng)將完整的代碼實(shí)例上傳到 github,github
地址為: https://github.com/fengshi123/request_example,歡迎 star 。
二、四種POST請(qǐng)求的Content-Type數(shù)據(jù)類型解析
1、application/x-www-form-unlencoded
最常見的 POST
提交數(shù)據(jù)的方式,瀏覽器的原生 form
表單,如果不設(shè)置 enctype
屬性,那么最終就會(huì)默認(rèn)以 application/x-www-form-urlencoded
方式提交數(shù)據(jù)。
1.1、前端請(qǐng)求代碼
var reqParam = "name=jack"; xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.send(reqParam);
1.2、服務(wù)端解析代碼
app.post('/urlencoded', bodyParser.urlencoded({extend:true}), function (req, res) { var result = { name: req.body.name, sex: '男', age: 15 }; res.send(result); });
1.3、瀏覽器請(qǐng)求 / 響應(yīng)截圖
請(qǐng)求:
響應(yīng):
2、multipart/form-data
使用表單上傳文件時(shí),必須指定表單的 enctype
屬性值為 multipart/form-data
. 請(qǐng)求體被分割成多部分,每部分使用 --boundary
分割開始,緊接著內(nèi)容描述信息,最后是字段具體內(nèi)容(文本或二進(jìn)制);如果傳輸?shù)氖俏募?,還要包含文件名和文件類型信息;
2.1、前端請(qǐng)求代碼
var reqParam = new FormData(document.form2); xhr.send(reqParam);
2.2、服務(wù)端解析代碼
express
提供了兩種插件 formidable
和 multiparty
來處理數(shù)據(jù)類型為 multipart/form-data
的情況,以下我們分別用兩個(gè)插件進(jìn)行處理;
2.2.1、formidable 插件
(1)安裝插件
npm install formidable --save
(2)服務(wù)端解析處理
app.post('/formData1', function (req, res) { var form = new formidable.IncomingForm(); form.uploadDir = "upload/"; form.parse(req, function (err, fields, files) { var obj = {}; Object.keys(fields).forEach(function (name) { obj[name] = fields[name]; }); Object.keys(files).forEach(function (name) { if (files[name] && files[name].name) { obj[name] = files[name]; fs.renameSync(files[name].path, form.uploadDir + files[name].name); } }); res.send(obj); }); });
2.2.2、multiparty 插件
(1)安裝插件
npm install multiparty--save
(2)服務(wù)端解析處理
app.post('/formData2', function (req, res) { // 解析一個(gè)文件上傳 var form = new multiparty.Form(); //設(shè)置編輯 form.encoding = 'utf-8'; //設(shè)置文件存儲(chǔ)路徑 form.uploadDir = "upload/"; //設(shè)置單文件大小限制 form.maxFilesSize = 2000 * 1024 * 1024; form.parse(req, function (err, fields, files) { var obj = {}; Object.keys(fields).forEach(function (name) { obj[name] = fields[name]; }); Object.keys(files).forEach(function (name) { if (files[name] && files[name][0] && files[name][0].originalFilename) { obj[name] = files[name]; fs.renameSync(files[name][0].path, form.uploadDir + files[name][0].originalFilename); } }); res.send(obj); }); });
2.3、瀏覽器請(qǐng)求 / 響應(yīng)截圖
請(qǐng)求:
響應(yīng):
3、application/json
application/json
這個(gè) Content-Type
作為響應(yīng)頭,用來告訴服務(wù)端消息主體是序列化后的 JSON
字符串。由于 JSON
規(guī)范的流行,除了低版本 IE
之外的各大瀏覽器都原生支持 JSON.stringify
,服務(wù)端語言也都有處理 JSON
的函數(shù),使用 JSON
不會(huì)遇上什么麻煩。
3.1、前端請(qǐng)求代碼
var reqParam = { name: 'jack' }; xhr.setRequestHeader('Content-type', 'application/json'); xhr.send(JSON.stringify(reqParam));
3.2、服務(wù)端解析代碼
app.post('/applicationJson', bodyParser.json(), function (req, res) { var result = { name: req.body.name, sex: '男', age: 15 }; res.send(result); });
3.3、瀏覽器請(qǐng)求 / 響應(yīng)截圖
請(qǐng)求:
響應(yīng):
4、text/xml
它是一種使用 HTTP
作為傳輸協(xié)議, XML
作為編碼方式的遠(yuǎn)程調(diào)用規(guī)范,它的使用也很廣泛,能很好的支持已有的 XML-RPC
服務(wù)。不過, XML
結(jié)構(gòu)還是過于臃腫,一般場(chǎng)景用 JSON
會(huì)更靈活方便。
4.1、前端請(qǐng)求代碼
var text = '<?xml version="1.0"?><methodCall><methodName>examples.getStateName</methodName>' + '<params><param><value><i4>41</i4></value></param></params></methodCall>'; xhr.setRequestHeader('Content-type', 'text/xml'); xhr.send(text);
4.2、服務(wù)端解析代碼
app.post('/textXml', bodyParser.urlencoded({extend:true}), function (req, res) { var result = ''; req.on('data', function (chunk) { result += chunk; }); req.on('end', function () { res.send(result); }); });
4.3、瀏覽器請(qǐng)求 / 響應(yīng)截圖
請(qǐng)求:
響應(yīng):
三、踩坑匯總
1、對(duì)于跨域請(qǐng)求,當(dāng) contentType
改為 application/json
,將觸發(fā)瀏覽器發(fā)送一個(gè)預(yù)檢 OPTIONS
請(qǐng)求到服務(wù)器,再發(fā)送正常的 post
請(qǐng)求;
2、使用 new FormData()
,然后設(shè)置 Content-type
為 application/x-www-form-urlencoded
或者 multipart/form-data
會(huì)導(dǎo)致后端無法正常解析,解決方法:就是不進(jìn)行頭部設(shè)置, Content-type
會(huì)默認(rèn) 為 multipart/form-data
,服務(wù)端正常解析;
3、 contentType
設(shè)置為 application/x-www-form-urlencoded
時(shí),傳給后端的請(qǐng)求參數(shù)為 JSON
字符串, chrome
調(diào)試框查看發(fā)送的請(qǐng)求參數(shù)多了冒號(hào),如下所示:
這是因?yàn)?application/x-www-form-urlencoded
它將被解析成鍵值對(duì)展示,但是字符串進(jìn)去是沒有改變的,但是展示的時(shí)候能看見。解決方法:如果為 JSON
字符串,則設(shè)置數(shù)據(jù)類型為 application/json
;
四、總結(jié)
本文我們主要介紹 Post
請(qǐng)求的 4 種 Content-Type
數(shù)據(jù)類型,以及如何使用 Express
來對(duì)每種 Content-Type
類型進(jìn)行解析。已經(jīng)將完整的代碼實(shí)例上傳到 github
, github
地址為:https://github.com/fengshi123/request_example,歡迎 star 。 demo
截圖如下所示:
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
node?NPM庫增強(qiáng)版globby?Promise使用學(xué)習(xí)
這篇文章主要為大家介紹了node?NPM庫增強(qiáng)版globby?Promise使用學(xué)習(xí),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07node實(shí)現(xiàn)基于token的身份驗(yàn)證
這篇文章主要介紹了node實(shí)現(xiàn)基于token的身份驗(yàn)證,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié)
這篇文章主要介紹了nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié),對(duì)FS模塊的大部份異步函數(shù)做了介紹,而且用中文注釋,這下用起來方便了,需要的朋友可以參考下2014-06-06node.js入門教程之querystring模塊的使用方法
querystring模塊主要用來解析查詢字符串,下面這篇文章主要介紹了關(guān)于node.js中querystring模塊使用方法的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-02-02