简单概念
next()函数是中间件函数的标识,实现多个中间件连续就调用的关键,它的作用是把流转关系交给下一个中间件或者路由
如无定义下文app指的是const app = express()
注意点:
1. 必须写入中间件函数next()
2. 一定要在路由之前注册中间件函数(错误类型的中间件除外)
3. 客户端发来的请求可以连续调用多个中间件
4. 为了防止混乱调用完next()后不要再写多余的代码
5. 连续调用多个中间件的时候共享请求对象request和响应对象response
const express = require('express')
const router = require('./router')
const app = express()
const vm = function(request, response, next) {
console.log('中间件函数')
const statrtime = new Date()
request.statrtime = statrtime
// 必须写入next()函数不然后边没办反请求到
next()
}
//到达路由之前会先调用中间件函数
app.use(vm).use(router)
app.use(router).use(vm)
//路由模块形式调用顺序并不会影响中间件的调用,但是多个中间件的顺序还是受到调用顺序的影响
app.use(vm2).use(vm).use(router)
//为了避免错乱,需要先执行的放到前边
app.use(vm1).use(vm2).use(router)
app.listen(8081, () => {
console.log('启动成功')
})
全局中间件
使用app.use()或者router.use()注册的中间件为全局中间件
const express = require('express')
const router = require('./router')
const app = express()
const vm = function(request, response, next) {
console.log('中间件函数')
next()
}
app.use(vm)
const express = require('express')
const router = express.Router()
const vm = function(request, response, next) {
console.log('路由级别中间件函数')
next()
}
router.use(vm)
局部中间件
const vm2 = function(request, response, next) {
console.log('中间件函数2')
const statrtime = new Date()
request.statrtime = statrtime
// 必须写入next()函数不然后边没办反请求到
next()
}
// 局部中间件,只会在当前路由生效
app.get('/lan', vm3, (res, req) => {
req.send("响应成功局部中间件" + res.statrtime)
})
调用多个
const vm = function(request, response, next) {
console.log('中间件函数')
// 必须写入next()函数不然后边没办反请求到
next()
}
const vm2 = function(request, response, next) {
console.log('中间件函数2')
const statrtime = new Date()
request.statrtime = statrtime
// 必须写入next()函数不然后边没办反请求到
next()
}
const vm3 = function(request, response, next) {
console.log('局部中间件')
const statrtime = new Date()
request.statrtime = statrtime
next()
}
const vm4 = function(request, response, next) {
console.log('局部中间件2')
const statrtime = new Date()
request.statrtime = statrtime
next()
}
//全局调用多个
app.use(vm).use(vm2).use(router)
// 局部定义多个中间件数组形式
app.get('/lans', [vm3, vm4], (res, req) => {
req.send("响应成功局部中间件" + res.statrtime)
})
// 局部定义多个中间件中间件另一种逗号分割
app.get('/lans2', vm3, vm4, (res, req) => {
req.send("响应成功局部中间件" + res.statrtime)
})
中间件分类
- 应用级别
- 路由级别
- 错误级别
- express内置的
- 第三方的(或自定义的)
应用级别
app.use()、app.get()、app.post()通过app挂载的
//应用级别的全局中间件函数
app.use((request, response, next) => {
next()
})
// 应用级别局部中间件函数
app.get('/lan', vm3, (res, req) => {
req.send("响应成功局部中间件")
})
路由级别
路由级别与应用级别一样,只是由app转到了router
const express = require('express')
const router = express.Router()
const vm = function(request, response, next) {
console.log('路由级别')
next()
}
// 路由级别的中间件
router.use(vm)
router.get('/us', vm, (request, response) => {
response.send('get请求/us')
})
错误级别
错误级别中间件函数要写到最后,程序由上至下执行,当执行遇到错误,会向下查找错误中间件函数,查到了执行错误中间件函数,查不到程序崩溃
// 定义一个错误的路由
app.get('/erro', vm3, vm4, (res, req) => {
throw new Error("服务器错误")
req.send("错误的请求")
})
// 错误中间件写在后边,四个参数,防止程序崩溃
app.use((erro, res, req, next) => {
console.log(erro)
req.send("错误的请求" + erro.message)
})
express内置的
常用的有以下三种:
- express.static 托管静态资源的
- express. json 解析JSON格式的请求体
- express. urlencoded解析x-www-form-urlencoded格式的请求体
const express = require('express')
const app = express()
app.use('public', express.static ('./file'))
app.use(express.json())
默认写法
app.use(express.urlencoded({ extended: false }))
第三方的
如body-parser,它是解析请求体的,类似内置的,安装后使用 npm i body-parser
const express = require('express')
const bodyParse = require('body-parser')
const app = express()
// app.use(bodyParse.urlencoded({ extended: false }))
app.post('/data', (req, res) => {
console.log(req)
res.send({
status: 0
})
})
app.listen(8081, () => {
console.log('启动成功')
})