node.js學(xué)習(xí)(10)——express中間件—body-parser獲取post、get數(shù)據(jù)

上一節(jié)-node.js學(xué)習(xí)(9)—express框架基本用法

上節(jié)我們講解了express的基本用法以及通過(guò)前臺(tái)獲取node服務(wù)器返回的數(shù)據(jù)。但是,有個(gè)問(wèn)題,當(dāng)時(shí)我們只介紹了服務(wù)端接收到請(qǐng)求并返回給前臺(tái)數(shù)據(jù),并沒(méi)有細(xì)說(shuō)服務(wù)器怎么取到前臺(tái)傳過(guò)來(lái)的數(shù)據(jù)(只是簡(jiǎn)單提及了get請(qǐng)求通過(guò)req.query可以拿到參數(shù),post卻沒(méi)有)。本節(jié)我們著重講解服務(wù)端獲取請(qǐng)求的參數(shù)

1542712902(1).jpg

1.post請(qǐng)求——req.query

//form.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <form action="http://localhost:8080/user"  method='get'>
        賬號(hào):<input type="text" name="name">
        <input type="submit" value="提交">
    </form>
</body>
</html>

//server.js
const express=require('express');
var server=express();
server.listen(8080);


server.get('/user',function(req,res){
    console.log(req.query); 
})

經(jīng)測(cè)試,我們可以通過(guò)req.query得到get請(qǐng)求的參數(shù)。

1.在express中,已經(jīng)封裝好獲取get參數(shù)的方法,即req.query,但是post請(qǐng)求的參數(shù)卻沒(méi)有被封裝,需要我們借助中間件(body-parser)來(lái)獲取。

2.post請(qǐng)求——中間件body-parser

express框架內(nèi)置body-parser中間件,不需要在單獨(dú)安裝,我們可以使用它來(lái)獲取post參數(shù)?,F(xiàn)在我們修改form.html的method屬性為post提交,然后修改server.js

const express=require('express');
const server=express();
const bodyParser = require('body-parser');

server.listen(8080,function(){
    console.log('http://localhost:8080');
});
server.use(bodyParser.urlencoded()); //調(diào)用中間件
server.post('/user',function(req,res){
    console.log(req.body); 
})

經(jīng)測(cè)試,我們已經(jīng)可以通過(guò)req.body得到post請(qǐng)求的參數(shù)。

1.express通過(guò)use來(lái)調(diào)用中間件server.use(中間件函數(shù))
2.通過(guò)server.use(bodyParser.urlencoded())調(diào)用中間件后,中間件的作用將會(huì)在下面所有的代碼中生效,所以req會(huì)增加body參數(shù)
3.bodyParser其實(shí)還有很多參數(shù)配置,我們這里面并沒(méi)有介紹,具體可以到github上面找到官方文檔

3.express鏈?zhǔn)讲僮?/h2>

在express中若訪問(wèn)相同地址,則會(huì)形成鏈?zhǔn)讲僮?。什么意思?我們看例子?/p>

//server.js
const express=require('express');
const server=express();
const bodyParser = require('body-parser');

server.listen(8080,function(){
    console.log('http://localhost:8080');
});
server.post('/user',function(req,res){
    console.log(1); 
})
server.post('/user',function(req,res){
    console.log(2); 
})

經(jīng)測(cè)試上面代碼,我們會(huì)發(fā)現(xiàn)只輸出了1,并沒(méi)有輸出2,當(dāng)我們有多條訪問(wèn)統(tǒng)一路徑的語(yǔ)句時(shí)候,就會(huì)形成鏈?zhǔn)讲僮鳎J(rèn)只執(zhí)行第一個(gè),需要手動(dòng)調(diào)用來(lái)執(zhí)行下一步?,F(xiàn)在我們修改代碼如下:

const express=require('express');
const server=express();
const bodyParser = require('body-parser');

server.listen(8080,function(){
    console.log('http://localhost:8080');
});
server.post('/user',function(req,res,next){
    console.log(1); 
    next();
})
server.post('/user',function(req,res,next){
    console.log(2); 
})

我們?cè)诨卣{(diào)函數(shù)中增加地三個(gè)參數(shù)——next,通過(guò)調(diào)用next()來(lái)進(jìn)行下一步操作,經(jīng)測(cè)試結(jié)果,我們會(huì)發(fā)現(xiàn)輸出了1和2。

1.鏈?zhǔn)讲僮?,你可以?jiǎn)單理解是規(guī)定這個(gè)操作流程有一個(gè)步驟,即需要先做什么,然后做什么。依次下去形成一個(gè)“流水線”。我們可以通過(guò)next來(lái)選擇是否進(jìn)行下一步操作

4.自己編寫(xiě)中間件

在上面我們使用了body-parser中間件來(lái)獲取post提交的參數(shù),那么我們?cè)趺磳?xiě)一個(gè)類似的中間件呢?接下來(lái),我們就以body-parser為例子,看看怎么實(shí)現(xiàn)它。

在編寫(xiě)中間件前,我們先看個(gè)小例子:

const express=require('express');
const server=express();

server.listen(8080,function(){
    console.log('http://localhost:8080');
});
server.post('/user',function(req,res,next){
    req.test=1
    next()
})
server.use('/user',function(req,res,next){
    console.log(req.test); //1
})

我們兩條語(yǔ)句都為/user(盡管一個(gè)為post一個(gè)為use),所以為鏈?zhǔn)讲僮?。我們?cè)诘谝淮危oreq增加一個(gè)test屬性,在第二次打印這個(gè)屬性,發(fā)現(xiàn)可以正確輸出。說(shuō)明鏈?zhǔn)讲僮髦?,req是可以傳遞的。即后面的req參數(shù)等于上一步的req參數(shù)

了解了參數(shù)傳遞后,我們開(kāi)始正式編寫(xiě)body-parser中間件。之前我們?cè)?a href="http://www.itdecent.cn/p/e29e64e8644b" target="_blank">node.js學(xué)習(xí)(5)——form提交數(shù)據(jù)(post)中,曾講過(guò)原生獲取post參數(shù)的方法。實(shí)際body-parser中間件便是通過(guò)該方法來(lái)封裝的。接下來(lái)看代碼:

const express=require('express');
const server=express();
const querystring = require('querystring');


server.listen(8080,function(){
    console.log('http://localhost:8080');
});


server.use(function(req,res,next){//沒(méi)有第一個(gè)參數(shù),則對(duì)所有路徑請(qǐng)求都接收
    var str = '';
    req.on('data',function(data){
        str+=data;
    });
    req.on('end',function(){
        req.body = querystring.parse(str);  //解析字符串
        next();  //因?yàn)槟J(rèn)接收所有路徑,所以當(dāng)使用時(shí)會(huì)和其他語(yǔ)句形成鏈?zhǔn)讲僮?,所以需要增加next
    });
});
//現(xiàn)在我們測(cè)試下,增加下面代碼
server.use('/user',function(req,res,next){
    console.log(req.body);
})

經(jīng)測(cè)試,我們可以輸出form表單提交的值。上面我們可以簡(jiǎn)單實(shí)現(xiàn)一個(gè)body-parser(僅僅獲取post數(shù)據(jù),實(shí)際的body-parser還有很多配置項(xiàng)等方法)。現(xiàn)在我們開(kāi)始封裝此中間件。
很簡(jiǎn)單,我們把上面原生的函數(shù)抽離出來(lái)放到一個(gè)提前建好的body-parser.js文件并導(dǎo)出。

module.exports={
    urlencoded:function(req,res,next){//沒(méi)有第一個(gè)參數(shù),則對(duì)所有路徑請(qǐng)求都接收
        var str = '';
        req.on('data',function(data){
            str+=data;
        });
        req.on('end',function(){
            req.body = querystring.parse(str);  //解析字符串
            next();  //因?yàn)槟J(rèn)接收所有路徑,所以當(dāng)使用時(shí)會(huì)和其他語(yǔ)句形成鏈?zhǔn)讲僮鳎孕枰黾觧ext
        });
    }
}

然后我們引入進(jìn)去,

const express=require('express');
const server=express();
const bodyParser=require('./body-parser');

server.listen(8080,function(){
    console.log('http://localhost:8080');
});

server.use(bodyParser.urlencoded()) //使用導(dǎo)入過(guò)來(lái)的中間件

//現(xiàn)在我們測(cè)試下,增加下面代碼,可以正確拿到post參數(shù)
server.use('/user',function(req,res,next){
    console.log(req.body);
})

查閱body-parser文檔,發(fā)現(xiàn)里面還有很多方法,我們自己封裝的中間件,只是實(shí)現(xiàn)了獲取post數(shù)據(jù)的功能,如果有時(shí)間,可以再拓展。

下一節(jié)-node.js學(xué)習(xí)(11)—cookie和session的使用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容