上一節(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ù)

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í)間,可以再拓展。