express.js中間件說明詳解
express的新開發(fā)人員往往對(duì)路由處理程序和中間件之間的區(qū)別感到困惑。因此他們也對(duì)app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()方法的區(qū)別感到困惑。
在本文中,我將解釋中間件和路由處理程序之間的區(qū)別。以及如何正確使用app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()方法。
路由處理
app.use(),app.all(),app.get(),app.post(),app.delete()和app.put()全部是用來定義路由的。這些方法都用于定義路由。路由用于處理HTTP請(qǐng)求。路由是路徑和回調(diào)的組合,在請(qǐng)求的路徑匹配時(shí)執(zhí)行?;卣{(diào)被稱為路由處理程序。
它們之間的區(qū)別是處理不同類型的HTTP請(qǐng)求。例如: app.get()方法僅僅處理get請(qǐng)求,而app.all()處理GET、POST等請(qǐng)求。
下面是一個(gè)例子,如何定義一個(gè)路由:
var app = require("express")();
app.get("/", function(req, res, next){
res.send("Hello World!!!!");
});
app.listen(8080);
每個(gè)路由處理程序都獲得對(duì)當(dāng)前正在提供的HTTP請(qǐng)求的請(qǐng)求和響應(yīng)對(duì)象的引用。
可以為單個(gè)HTTP請(qǐng)求執(zhí)行多個(gè)路由處理程序。這是一個(gè)例子:
var app = require("express")();
app.get("/", function(req, res, next){
res.write("Hello");
next();
});
app.get("/", function(req, res, next){
res.write(" World !!!");
res.end();
});
app.listen(8080);
這里第一個(gè)句柄寫入一些響應(yīng),然后調(diào)用next()。 next()方法用于調(diào)用與路徑路徑匹配的下一個(gè)路由處理程序。
路由處理程序必須結(jié)束請(qǐng)求或調(diào)用下一個(gè)路由處理程序。
我們還可以將多個(gè)路由處理程序傳遞給app.all(),app.get(),app.post(),app.delete()和app.put()方法。
這是一個(gè)證明這一點(diǎn)的例子:
var app = require("express")();
app.get("/", function(req, res, next){
res.write("Hello");
next();
}, function(req, res, next){
res.write(" World !!!");
res.end();
});
app.listen(8080);
中間件
中間件是一個(gè)位于實(shí)際請(qǐng)求處理程序之上的回調(diào)。它采用與路由處理程序相同的參數(shù)。
要了解中間件,我們來看一個(gè)帶有dashboard和profile頁面的示例站點(diǎn)。要訪問這些頁面,用戶必須登錄。還會(huì)記錄對(duì)這些頁面的請(qǐng)求。
以下是這些頁面的路由處理程序的代碼:
var app = require("express")();
function checkLogin(){
return false;
}
function logRequest(){
console.log("New request");
}
app.get("/dashboard", function(req, res, next){
logRequest();
if(checkLogin()){
res.send("This is the dashboard page");
}
else{
res.send("You are not logged in!!!");
}
});
app.get("/profile", function(req, res, next){
logRequest();
if(checkLogin()){
res.send("This is the dashboard page");
}
else{
res.send("You are not logged in!!!");
}
});
app.listen(8080);
這里的問題是有很多重復(fù)的代碼,即我們不得不多次使用logRequest()和checkLogin()函數(shù)。這也使得更新代碼變得困難。因此,為了解決這個(gè)問題,我們可以為這兩條路徑編寫一條通用路徑。
這是重寫的代碼:
var app = require("express")();
function checkLogin(){
return false;
}
function logRequest(){
console.log("New request");
}
app.get("/*", function(req, res, next){
logRequest();
next();
})
app.get("/*", function(req, res, next){
if(checkLogin()){
next();
}
else{
res("You are not logged in!!!");
}
})
app.get("/dashboard", function(req, res, next){
res.send("This is the dashboard page");
});
app.get("/profile", function(req, res, next){
res.send("This is the dashboard page");
});
app.listen(8080);
這里的代碼看起來更清晰,更易于維護(hù)和更新。這里將前兩個(gè)定義的路由處理程序稱為中間件,因?yàn)樗鼈儾惶幚碚?qǐng)求,而是負(fù)責(zé)預(yù)處理請(qǐng)求。
Express為我們提供了app.use()方法,該方法專門用于定義中間件。 app.use()方法可能看起來與app.all()類似,但它們之間存在很多差異,這使得app.use()非常適合于聲明中間件。讓我們看看app.use()方法是如何工作的:
app.use() 和 app.all() 的不同:
CALLBACK
app.use()只需要一個(gè)回調(diào),而app.all()可以進(jìn)行多次回調(diào)。
PATH
app.use()只查看url是否以指定路徑開頭,app.all()匹配完整路徑。
這里有一個(gè)例子來說明:
app.use( "/product" , mymiddleware); // will match /product // will match /product/cool // will match /product/foo app.all( "/product" , handler); // will match /product // won't match /product/cool <-- important // won't match /product/foo <-- important app.all( "/product/*" , handler); // won't match /product <-- Important // will match /product/cool // will match /product/foo
NEXT()
中間件內(nèi)的next()調(diào)用下一個(gè)中間件或路由處理程序,具體取決于接下來聲明的那個(gè)。但是路由處理程序中的next()僅調(diào)用下一個(gè)路由處理程序。如果接下來有中間件,則跳過它。因此,必須在所有路由處理程序之前聲明中間件。
這里有一個(gè)例子來說明:
var express = require('express');
var app = express();
app.use(function frontControllerMiddlewareExecuted(req, res, next){
console.log('(1) this frontControllerMiddlewareExecuted is executed');
next();
});
app.all('*', function(req, res, next){
console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next');
next();
});
app.all('/hello', function(req, res, next){
console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next');
next();
});
app.use(function frontControllerMiddlewareNotExecuted(req, res, next){
console.log('(4) this frontControllerMiddlewareNotExecuted is not executed');
next();
});
app.get('/hello', function(req, res){
console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response');
res.send('Hello World');
});
app.listen(80);
現(xiàn)在我們看到了app.use()方法的唯一性以及它用于聲明中間件的原因。
讓我們重寫我們的示例站點(diǎn)代碼:
var app = require("express")();
function checkLogin(){
return false;
}
function logRequest(){
console.log("New request");
}
app.use(function(req, res, next){
logRequest();
next();
})
app.use(function(req, res, next){
if(checkLogin()){
next();
}
else{
res.send("You are not logged in!!!");
}
})
app.get("/dashboard", function(req, res, next){
res.send("This is the dashboard page");
});
app.get("/profile", function(req, res, next){
res.send("This is the dashboard page");
});
app.listen(8080);
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
VsCode與Node.js知識(shí)點(diǎn)詳解
在本篇文章中小編給大家分享了關(guān)于VsCode與Node.js的相關(guān)知識(shí)點(diǎn)以及安裝等內(nèi)容,需要的朋友們可以參考下。2019-09-09
使用Node.js實(shí)現(xiàn)一個(gè)文章生成器
本文將從零開始,講解如何使用Node.js來實(shí)現(xiàn)一個(gè)文章生成器,node里面有很多優(yōu)秀的模塊,現(xiàn)在我們就借助node的fs模塊來操控文本,來實(shí)現(xiàn)我們想要的效果,感興趣的小伙伴跟著小編一起來看看吧2024-07-07
Node連接MySQL并封裝其增刪改查的實(shí)現(xiàn)代碼
本文主要介紹了Node連接MySQL并封裝其增刪改查的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
Node.JS在命令行中檢查Chrome瀏覽器是否安裝并打開指定網(wǎng)址
這篇文章主要介紹了Node.JS在命令行中檢查Chrome瀏覽器是否安裝,并打開指定網(wǎng)址,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
Mongoose中document與object的區(qū)別示例詳解
這篇文章主要給大家介紹了關(guān)于Mongoose中document與object區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-09-09
NPM配置私服構(gòu)建內(nèi)網(wǎng)中央倉庫過程詳解
這篇文章主要為大家介紹了NPM配置私服構(gòu)建內(nèi)網(wǎng)中央倉庫過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

