Express基礎瞭解—中介軟體
主要根據官方文件和網上資料整理的。
參考文章:
http://www.expressjs.com.cn/guide/using-middleware.html
http://www.html-js.com/article/1603
https://segmentfault.com/q/1010000000510541
https://www.jianshu.com/p/797a4e38fe77
Express 是一個自身功能極簡,完全是由路由和中介軟體構成一個的 web 開發框架:從本質上來說,一個 Express 應用就是在呼叫各種中介軟體。
中介軟體(Middleware) 是一個函式,它可以訪問 請求物件(request object (req)), 響應物件(response object (res)), 和 web 應用中處於請求-響應迴圈流程中的中介軟體,一般被命名為 next 的變數。
中介軟體的功能包括:
- 執行任何程式碼。
- 修改請求和響應物件。
- 終結請求-響應迴圈。
- 呼叫堆疊中的下一個中介軟體。
如果當前中介軟體沒有終結請求-響應迴圈,則必須呼叫 next() 方法將控制權交給下一個中介軟體,否則請求就會掛起。
Express 應用可使用如下幾種中介軟體:
- 應用級中介軟體
- 路由級中介軟體
- 錯誤處理中介軟體
- 內建中介軟體
- 第三方中介軟體
使用可選則掛載路徑,可在應用級別或路由級別裝載中介軟體。另外,你還可以同時裝在一系列中介軟體函式,從而在一個掛載點上建立一個子中介軟體棧。
應用級中介軟體:
應用級中介軟體繫結到app物件使用app.use()和app.METHOD(),其中,METHOD是需要處理的HTTP請求的方法,例如GET,PUT,POST等等,全部小寫。例如:
var app = express();
// 沒有掛載路徑的中介軟體,應用的每個請求都會執行該中介軟體
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
});
// 掛載至 /user/:id 的中介軟體,任何指向 /user/:id 的請求都會執行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
// 路由和控制程式碼函式(中介軟體系統),處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
});
下面這個例子展示了在一個掛載點裝載一組中介軟體。
// 一箇中介軟體棧,對任何指向 /user/:id 的 HTTP 請求列印出相關資訊
app.use('/user/:id', function(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}, function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
作為中介軟體系統的路由控制程式碼,使得為路徑定義多個路由成為可能。在下面的例子中,為指向 /user/:id 的 GET 請求定義了兩個路由。第二個路由雖然不會帶來任何問題,但卻永遠不會被呼叫,因為第一個路由已經終止了請求-響應迴圈。
// 一箇中介軟體棧,處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
console.log('ID:', req.params.id);
next();
}, function (req, res, next) {
res.send('User Info');
});
// 處理 /user/:id, 列印出使用者 id
app.get('/user/:id', function (req, res, next) {
res.end(req.params.id);
});
如果需要在中介軟體棧中跳過剩餘中介軟體,呼叫 next(‘route’) 方法將控制權交給下一個路由。 注意: next(‘route’) 只對使用 app.VERB() 或 router.VERB() 載入的中介軟體有效。
// 一箇中介軟體棧,處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
// 如果 user id 為 0, 跳到下一個路由
if (req.params.id == 0) next('route');
// 否則將控制權交給棧中下一個中介軟體
else next(); //
}, function (req, res, next) {
// 渲染常規頁面
res.render('regular');
});
// 處理 /user/:id, 渲染一個特殊頁面
app.get('/user/:id', function (req, res, next) {
res.render('special');
});
路由級中介軟體:
路由級中介軟體和應用級中介軟體一樣,只是它繫結的物件為express.Router()。
var router = express.Router();
路由級使用router.use()或router.VERB()載入。
# 1. 宣告路由級中介軟體
var express = require('express');
// 路由中介軟體
var router = express.Router();
router.get('/',function (req,res,next) {
res.send('root');
})
// 路由中介軟體 匯出
module.exports = router;
# 2. 呼叫路由級中介軟體
var express = require('express');
var app = express();
// 引入 路由中介軟體
var indexRouter = require('./test3')
// 路由中介軟體的使用
app.use('/',indexRouter);
app.listen(3000);
console.log('Listen to port 3000');
錯誤處理中介軟體:
錯誤處理中介軟體有4個引數,定義錯誤處理中介軟體必須使用這4個引數。即使不需要next物件,也必須在簽名中宣告它,否則中介軟體會被識別為一個常規中介軟體,不能處理錯誤。
app.use(function(err,req,res,next){
console.error(err,stack);
res.status(500).send('Somthing broke!');
});
內建中介軟體:
除了express.static,Express以前內建的中介軟體現在已經全部單獨作為模組安裝使用了。
第三方中介軟體:
通過使用第三方中介軟體從而為 Express 應用增加更多功能。
安裝所需功能的 node 模組,並在應用中載入,可以在應用級載入,也可以在路由級載入。
下面的例子安裝並載入了一個解析 cookie 的中介軟體: cookie-parser
$ npm install cookie-parser
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');
// 載入用於解析 cookie 的中介軟體
app.use(cookieParser());
中介軟體的執行順序:https://www.jianshu.com/p/797a4e38fe77
/**
* express中介軟體的實現和執行順序
*
* Created by BadWaka on 2017/3/6.
*/
var express = require('express');
var app = express();
app.listen(3000, function () {
console.log('listen 3000...');
});
function middlewareA(req, res, next) {
console.log('middlewareA before next()');
next();
console.log('middlewareA after next()');
}
function middlewareB(req, res, next) {
console.log('middlewareB before next()');
next();
console.log('middlewareB after next()');
}
function middlewareC(req, res, next) {
console.log('middlewareC before next()');
next();
console.log('middlewareC after next()');
}
app.use(middlewareA);
app.use(middlewareB);
app.use(middlewareC);
執行結果:
其他一些中介軟體例子:
Express中介軟體:
var express = require('express');
var app = express();
// 沒有掛載路徑的中介軟體,應用的每個請求都會執行該中介軟體
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
console.log('First');
});
// 掛載至 /user/:id 的中介軟體,任何指向 /user/:id 的請求都會執行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
console.log('Second');
});
// 路由和控制程式碼函式(中介軟體系統),處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
console.log('路由和中介軟體,app.get({})');
});
app.listen(3000);
console.log('Listen to port 3000');
輸出結果:
Listen to port 3000
Time: 1532480196062
Request Type: GET
路由和中介軟體,app.get({})
Second
First
Express中介軟體:(新增了中介軟體的巢狀)
var express = require('express');
var app = express();
// 沒有掛載路徑的中介軟體,應用的每個請求都會執行該中介軟體
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
console.log('First');
});
// 掛載至 /user/:id 的中介軟體,任何指向 /user/:id 的請求都會執行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
console.log('Second');
});
// 在一個掛載點裝載一組中介軟體,就是中介軟體裡面巢狀中介軟體
app.use('/user/:id',function (req,res,next) {
console.log('Request URL:',req.originalUrl);
next();
},function (req,res,next) {
console.log('中介軟體的巢狀');
next();
})
// 路由和控制程式碼函式(中介軟體系統),處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
console.log('路由和中介軟體,app.get({})');
});
app.listen(3000);
console.log('Listen to port 3000');
輸出結果:
Listen to port 3000
Time: 1532480581762
Request Type: GET
Request URL: /user/1
中介軟體的巢狀
路由和中介軟體,app.get({})
Second
First
Express中介軟體(新增了內建中介軟體):
var express = require('express');
var app = express();
// 沒有掛載路徑的中介軟體,應用的每個請求都會執行該中介軟體
app.use(function (req, res, next) {
console.log('Time:', Date.now());
next();
console.log('First');
});
// 掛載至 /user/:id 的中介軟體,任何指向 /user/:id 的請求都會執行它
app.use('/user/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
console.log('Second');
});
// 在一個掛載點裝載一組中介軟體,就是中介軟體裡面巢狀中介軟體
app.use('/user/:id',function (req,res,next) {
console.log('Request URL:',req.originalUrl);
next();
},function (req,res,next) {
console.log('中介軟體的巢狀');
next();
})
// 路由和控制程式碼函式(中介軟體系統),處理指向 /user/:id 的 GET 請求
app.get('/user/:id', function (req, res, next) {
res.send('USER');
console.log('路由和中介軟體,app.get({})');
});
// 內建中介軟體
var bodyParser = require('body-parser'); //
app.use(bodyParser.urlencoded({ extended:false })) //
// 此時public相對於根目錄了,通過localhost:3000/nodejs.png 就可以訪問到這個圖片了
app.use(express.static('public'))
app.listen(3000);
console.log('Listen to port 3000');
相關文章
- Express基礎瞭解—路由Express路由
- Express中介軟體原理詳解Express
- Express基礎瞭解—模板引擎Express
- 理解Express中介軟體Express
- Express 文件(使用中介軟體)Express
- Express框架(二)—— 中介軟體Express框架
- Express 實戰(四):中介軟體Express
- 「翻譯」express-session 中介軟體ExpressSession
- Koa和Express的非同步中介軟體解決辦法Express非同步
- Express的使用筆記3 中介軟體Express筆記
- Express與Koa中介軟體機制分析(二)Express
- Express 中介軟體 getcookies 後門程式碼分析ExpressCookie
- Express與Koa中介軟體機制分析(一)Express
- Express中介軟體body-parser簡單實現Express
- redux, koa, express 中介軟體實現對比解析ReduxExpress
- node JS 中 express 中介軟體實現原理分析JSExpress
- 訊息型中介軟體之RabbitMQ基礎使用MQ
- Express檔案表單解析中介軟體 Multer簡介Express
- 初識NodeJS-使用Express框架路由和中介軟體NodeJSExpress框架路由
- .NET Core基礎篇之:白話管道中介軟體
- 閃現, 請求擴充套件, 藍圖, 中介軟體(瞭解)套件
- ASP.NET Core 2.2 基礎知識(十)【中介軟體】ASP.NET
- Django基礎七之CBV裝飾器和中介軟體Django
- middleware 中介軟體詳解
- 好程式設計師Python培訓分享Django中介軟體基礎用法詳解程式設計師PythonDjango
- 好程式設計師Python培訓之Django中介軟體基礎用法詳解程式設計師PythonDjango
- (二)學習瞭解OrchardCore筆記——開篇:OrchardCore的中介軟體筆記
- Express使用進階:cookie-parser中介軟體實現深入剖析ExpressCookie
- Nodejs 進階:Express 常用中介軟體 body-parser 實現解析NodeJSExpress
- Asp.Net Core基礎篇之:白話管道中介軟體ASP.NET
- Redis中介軟體與Web中介軟體RedisWeb
- Express, Koa, Redux中介軟體的區別,寫法和執行流程ExpressRedux
- 中介軟體之訊息中介軟體-pulsar
- Nginx深入瞭解-基礎(一)Nginx
- Nginx深入瞭解-基礎(三)Nginx
- Java基礎系列:瞭解ArrayListJava
- 初步瞭解Express(基於node.js的後端框架)ExpressNode.js後端框架
- 資料庫中介軟體詳解資料庫