前言
中间件是Express框架中很重要,很核心的一部分。上一篇文章我们主要介绍了Express中的路由,而且一个Express应用就是在调用各种中间件。除了路由之外,Express还有一个核心内容就是中间件。我们这篇文章主要介绍中间件的作用和用法。
中间件
中间件本质上就是一个回调函数,它可以访问请求对象(req),响应对象(res)和next变量。
中间件的作用
中间件最核心的作用就是使用函数封装公共逻辑,简化代码。除此之外,中间件还具有以下功能。
- 执行任何代码
- 修改请求和响应对象(req, res)
- 终结请求-响应循环(res.end)
- 调用堆栈中的下一个中间件(next)
需要注意的是:如果当前中间件没有终结请求-响应循环,则必须调用next()方法将控制权交给下一个中间件。
中间件的类型
中间件有很多类型,一般可以分为以下几类:
- 应用级中间件
- 路由级中间件
- 错误处理中间件
- 内置中间件
- 第三方中间件
1. 应用级中间件
应用级中间件绑定到 app 对象 使用 app.use() 和 app.METHOD(),因此也叫全局中间件。 其中, METHOD 是需要处理的 HTTP 请求的方法,例如 GET, PUT, POST 等等,全部小写。
声明中间件
定义中间件的方法如下:
let recordMiddleWare = (req, res, next) => {
// 实现具体功能
console.log('这是一个中间件');
// 执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
next();
}
应用中间件
const express = require('express');
const app = express();
app.use(recordMiddleWare);
当然上述代码也可以写成这样:
app.use((req, res, next) => {
// 实现具体功能
console.log('这是一个中间件');
// 执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
next();
})
const express = require('express');
const app = express();
// 应用级组件(后面的路由都会执行这个中间件)
app.use((req, res, next) => {
// 验证token是否过期
let isValid = true;
if (isValid) {
next()
} else {
res.end('error');
}
});
2. 路由级中间件
很明显,路由级中间件是和全局中间件是不一样的,它更相当于是一个局部中间件,只有在特定路由下才能执行的中间件。路由级中间件是由app.route创建的,而且可以链式调用
const express = require('express');
const app = express();
app.route('/test')
.get((req, res) => {
res.send('get ok!')
})
.post((req, res) => {
res.send('post ok!')
});
也可以使用express的router类创建路由组件,一个Router实例是一个完整的中间件和路由系统,这种方式下可以导出给其他模板使用。
const app = express();
const router = express.Router();
// 没有挂载路径的中间件,通过该路由的每个请求都会执行该中间件
router.use(function (req, res, next) {
console.log('Time:', Date.now())
next()
})
// 一个中间件栈,显示任何指向 /user/:id 的 HTTP 请求的信息
router.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()
})
还可以使用router.route()方法创建路由组件,接受访问路径作为参数,这种方式下可以导出给其他模板使用。
const app = express();
const router = express.Router();
router.route('/test')
.get((req, res) => {
res.send('get ok!')
})
.post((req, res) => {
res.send('post ok!')
});
3.错误处理组件
错误处理组件就是用来处理错误逻辑的,接收四个参数,多了一个err.
const app = express();
app.use((err, req, res, next) => {
console.log('ERR', err)
res.send('err')
})
4. 内置的中间件
上面的中间件是我们自己定义的中间件,Express有自己的内置的中间件。也是唯一的内置中间件,那就是serve-static,主要是负责托管静态资源的。
//引入express框架
const express = require('express');
//创建服务对象
const app = express();
//静态资源中间件的设置,将当前文件夹下的public目录作为网站的根目录
app.use(express.static('./public')); //当然这个目录中都是一些静态资源
//如果访问的内容经常变化,还是需要设置路由
//但是,在这里有一个问题,如果public目录下有index.html文件,单独也有index.html的路由
//则谁书写在前,优先执行谁
app.get('/index.html',(request,response)=>{
respsonse.send('首页');
});
//监听端口
app.listen(3000,()=>{
console.log('3000 端口启动....');
});
需要注意以下几点:
- index.html 文件为默认打开的资源
- 如果静态资源与路由规则同时匹配,谁先匹配谁就响应
- 路由响应动态资源,静态资源中间件响应静态资源
5. 第三方中间件
网上有很多第三方中间件,我们可以下载这些第三方中间件来帮助处理我们的一些逻辑。比如 cookie-parser,它可以用于解析cookie。
第三方中间件的用法如下:
首先安装第三方组件
npm i cookie-parser
然后就可以使用第三方中间件了
const express = require('express')
const app = express()
const cookieParser = require('cookie-parser')
// 加载用于解析 cookie 的中间件
app.use(cookieParser())