[TOC]
# 中间件
概述:
  中间件是一类连接软件组件和应用的计算机软件,它包括一组服务。以便于运行在一台或多台机器上的多个软件通过网络进行交互。
  原生 Node.js 的单一请求处理函数,随着功能的扩张势必会变的越来越难以维护。而 Express 框架则可以通过中间件的方式按照模块和功能对处理函数进行切割处理。这样拆分后的模块不仅逻辑清晰,更重要的是对后期维护和开发非常有利。
![](https://img.kancloud.cn/32/5a/325a521a21680e02fcbd17c802f5c650_566x169.png)
<br>
<br>
<br>
![](https://img.kancloud.cn/d8/f7/d8f75f36c378a43772556adbfd2af5a0_566x586.png)
<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...');
});
```