next 函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。
Express中间件的demo
定义中间件函数
可以通过如下的方式,定义一个最简单的中间件函数:
// 常量 mw 所指向的,就是一个中间件函数 const mw = function (req, res, next) { console.log('这是一个简单的中间件函数'); // 注意:在当前中间件的业务处理完毕后,必须调用 next() 函数 // 表示把流转关系转交给下一个中间件或路由 next() }
全局生效的中间件
客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。
通过调用 app.use(中间件函数),即可定义一个全局生效的中间件,示例代码如下:
const express = require('express') const userRouter = require('./router') const app = express() // 常量 mw 所指向的,就是一个中间件函数 const mw = function (req, res, next) { console.log('这是一个简单的中间件函数'); // 注意:在当前中间件的业务处理完毕后,必须调用 next() 函数 // 表示把流转关系转交给下一个中间件或路由 next() } // 全局生效的中间件 // 注意:注册中间件在路由前注册 app.use(mw) // 使用 app.use() 注册路由模块 app.use(userRouter) app.listen(8080, () => { console.log('server is running'); })
定义全局中间件的简化形式
const express = require('express') const userRouter = require('./router') const app = express() // 全局生效的中间件 // 注意:注册中间件在路由前注册 app.use(function (req, res, next) { console.log('这是一个简单的中间件函数'); // 注意:在当前中间件的业务处理完毕后,必须调用 next() 函数 // 表示把流转关系转交给下一个中间件或路由 next() }) // 使用 app.use() 注册路由模块 app.use(userRouter) app.listen(8080, () => { console.log('server is running'); })
中间件的作用
多个中间件之间,共享同一份 req 和 res。基于这样的特性,我们可以在上游的中间件中,统一为 req 或 res 对象添 加自定义的属性或方法,供下游的中间件或路由进行使用。
定义多个全局中间件
可以使用 app.use() 连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行 调用,示例代码如下:
app.use(function (req, res, next) { console.log('调用了第一个全局中间件'); // 注意:在当前中间件的业务处理完毕后,必须调用 next() 函数 // 表示把流转关系转交给下一个中间件或路由 next() }) app.use(function (req, res, next) { console.log('调用了第二个全局中间件'); // 注意:在当前中间件的业务处理完毕后,必须调用 next() 函数 // 表示把流转关系转交给下一个中间件或路由 next() })
局部生效的中间件
不使用 app.use() 定义的中间件,叫做局部生效的中间件,示例代码如下:
// 定义中间件函数 mw1 const mw1 = function (req, res, next) { console.log('这是中间件函数') next() } // mw1 这个中间件只在当前路由中生效, 这种用法属于"局部生效的中间件" app.get('/', mw1, function (req, res) { res.send('home page.') }) // mw1 这个中间件不会影响下面这个路由 app.get('/user', function (req, res) { res.send('User page.') })
定义多个局部中间件
可以在路由中,通过如下两种等价的方式,使用多个局部中间件:
// 以下两种写法是完全等价的,可根据自己的喜好,选择任意一种方法进行使用 app.get('/', mw1, mw2, (req, res) => { res.send('Home page') }) app.get('/', [mw1, mw2], (req, res) => { res.send('Home page') })
了解中间件的5个使用注意事项
① 一定要在路由之前注册中间件
② 客户端发送过来的请求,可以连续调用多个中间件进行处理
③ 执行完中间件的业务代码之后,不要忘记调用 next() 函数
④ 为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
⑤ 连续调用多个中间件时,多个中间件之间,共享 req 和 res 对象
中间件的分类
为了方便大家理解和记忆中间件的使用,Express 官方把常见的中间件用法,分成了 5 大类,分别是:
① 应用级别的中间件
② 路由级别的中间件
③ 错误级别的中间件
④ Express 内置的中间件
⑤ 第三方的中间件
应用级别的中间件
通过 app.use() 或 app.get() 或 app.post() ,绑定到 app 实例上的中间件,叫做应用级别的中间件,代码示例如下:
// 应用级别的中间件 (全局中间件) app.use((req, res, next) => { next() }) // 应用级别的中间件 (局部中间件) app.get('/', mw1, (req, res) => { res.send('Home page') })