[TOC]
# 中間件
概述:
  中間件是一類連接軟件組件和應用的計算機軟件,它包括一組服務。以便于運行在一臺或多臺機器上的多個軟件通過網絡進行交互。
  原生 Node.js 的單一請求處理函數,隨著功能的擴張勢必會變的越來越難以維護。而 Express 框架則可以通過中間件的方式按照模塊和功能對處理函數進行切割處理。這樣拆分后的模塊不僅邏輯清晰,更重要的是對后期維護和開發非常有利。

<br>
<br>
<br>

<br>
**中間件(Middleware)本質就是一個函數,有個四個參數:**
1. **err:錯誤對象(錯誤處理件才會有)**
2. **req:請求對象;**
3. **res:響應對象**
4. **next:函數對象,一般稱之為 next ,它用于傳遞中間件棧對某個請求的處理流。**
  在整個中間件棧的處理流中,最少有一個函數需要通用 res.end() 方法結束響應處理。
## 手動實現中間件
需求,記錄請求時間,在控制臺打印
1. 原始代碼
```
// 版本 1,不單獨抽出中間件--
const express = require('express');
const app = express();
// 對 / 請求配置多個處理函數,注意第一個函數 next 參數,并調用
app.get('/', (req, res, next) => {
console.log(Date.now());
next(); // 若這里不顯示調用,下面那個函數就不會執行,也即不會響應。
}, (req, res) => {
res.send('Hello World!')
});
app.listen(8888, () => {
console.log('8888 Running...');
});
```
2. 單獨抽出中間件--內置中間件
```
// 版本 2,單獨抽出中間件--內置中間件
const express = require('express');
const app = express();
let myLogger = function (req, res, next) { // 中間件
console.log(Date.now());
next(); //繼續下一個函數
}
app.get('/', myLogger); // 應用中間
app.get('/', (req, res) => {
res.send('Hello World!');
})
app.listen(8888, () => {
console.log('8888 Running...');
});
```
3. 單獨抽出中間件,針對多種請求方式
```
// 版本 3,單獨抽出中間件,針對多種請求方式
const express = require('express');
const app = express();
let myLogger = function (req, res, next) { // 路由器中間件
console.log(Date.now());
next(); // 不能少了
}
//應用中間件
app.use(myLogger); // 省略路徑,默認是 “/”
app.get('/', (req, res) => {
res.send('Hello World Get!');
})
app.post('/', (req, res) => {
res.send('Hello World Post!');
})
app.listen(8888, () => {
console.log('8888 Running...');
});
```
4. 路由級別中間件
中間件文件
```
// 版本 4,單獨抽出中間模塊
// 文件位置 myapp/mylogger.js
let myLogger = function (req, res, next) {
console.log(Date.now());
next();
}
module.exports = myLogger;
```
js前端代碼
```
// 版本 4,單獨抽出中間模塊
// 文件位置 myapp/app.js
const myLogger = require('./mylogger.js'); //引入文件
const express = require('express'); //引入文件
const app = express();
app.use(myLogger);//應用中間件,針對多種請求方式
app.get('/', (req, res) => {
res.send('Hello World Get!');
})
app.post('/', (req, res) => {
res.send('Hello World Post!');
})
app.listen(8888, () => {
console.log('8888 Running...');
});
```
<br>
## 常用內置中間件和第三方中間件
**注意:第三方的中間件,使用前得安裝對相應的包。**
>[success] * 靜態文件服務中間件:express.static--內置
> * 日志中間件:morgan
> * 參數解析:body-parser
> * Cookie 解析:cookie-parser
> * 文件上傳解析:express-fileupload
例:
使用前先要先安裝包--npm install morgan
```
// 把上面 app.js 代碼構造一下
const morgan = require('morgan');//引入第三方中間件
const express = require('express');
const app = express();
app.use(morgan('dev')); // 應用第三方日志中間件
app.get('/', (req, res) => {
res.send('Hello World Get!');
});
app.post('/', (req, res) => {
res.send('Hello World Post!');
});
app.listen(8888, () => {
console.log('8888 Running...');
});
```