中间件
?express中间件的调用流程
express中间件的格式
?next函数的作用
?定义中间件函数
const express = require('express')
const app = express()
//定义一个最基本的中间件函数
const mw = function(req,res,next){
console.log("中间件函数")
//传递到下一个中间件或者后端路由
next()
}
app.listen(8000,()=>{console.log("监听8000端口")})
?全局生效的中间件
定义全局中间件的简化形式
?定义多个全局中间件
按照定义的先后顺序执行
(调用next后,不推荐再写逻辑)
?整个响应流程执行完后,再异步执行next后面的代码。
const express = require('express')
const app = express()
app.use((req,res,next)=>{
console.log("中间件函数2")
//传递到下一个中间件或者后端路由
next()
console.log("中间件函数22")
})
//定义一个最基本的中间件函数
const mw = function(req,res,next){
console.log("中间件函数1")
//传递到下一个中间件或者后端路由
next()
console.log("中间件函数11")
}
//组成全局生效的中间件
app.use(mw)
app.get('/user',(req,res)=>{
const data = {name:"jack"}
res.send(JSON.stringify(data))
console.log('回传数据')
})
app.listen(8000,()=>{console.log("监听8000端口")})
中间件的作用?
中间件和路由传递的是同一个req和res
const express = require('express')
const app = express()
app.use((req,res,next)=>{
req.time = Date.now()
console.log("中间件函数2:",req.time)
//传递到下一个中间件或者后端路由
next()
console.log("中间件函数22")
})
//定义一个最基本的中间件函数
const mw = function(req,res,next){
console.log("中间件函数1:",req.time)
//传递到下一个中间件或者后端路由
next()
console.log("中间件函数11")
}
//组成全局生效的中间件
app.use(mw)
app.get('/user',(req,res)=>{
const data = {name:"jack"}
res.send(JSON.stringify(data))
console.log('回传数据:',req.time)
})
app.listen(8000,()=>{console.log("监听8000端口")})
局部生效的中间件
在路由中局部注册中间件,此中间件只在当前路由生效
?定义多个局部中间件
const express = require('express')
const app = express()
const mw1 = (req,res,next)=>{
console.log('调用了中间件1')
next()
}
const mw2 = (req,res,next)=>{
console.log('调用了中间件2')
next()
}
app.get('/',(req,res)=>{
res.send('Home')
})
app.get('/user',mw1,mw2,(req,res)=>{
res.send('user')
})
app.listen(8000,()=>{console.log("监听8000端口")})
?中间件的5个使用注意事项
在路由之前注册
const express = require('express')
const app = express()
const mw = (req,res,next)=>{
console.log("中间件")
next()
}
app.use(mw)
app.get('/',(req,res)=>{
res.send("msg")
})
//app.use(mw) //不生效
app.listen(8000,()=>{console.log("监听8000端口")})
中间件的分类?
?应用级别的中间件
绑定到app实例上的中间件
全局注册,局部注册?
?路由级别的中间件
绑定到router实例上的中间件
?错误级别的中间件
捕获异常
放在路由之前的中间件是为了预先处理一些事件,在开始响应客户端请求
错误中间件是放在最后面,是为了捕获到路由发生的错误,所以得放在最后面
注意:错误级别中间件,必须注册在所有路由之后!?
如果将错误级别中间件,放在路由前面,还是会报错
const express = require('express')
const app = express()
app.get('/error',(req,res)=>{
throw new Error('服务器发生错误!')
res.send('msg')
})
app.use((err,req,res,next)=>{
console.log('发生错误' + err)
//返回给客户端的消息
res.send("Error!")
})
app.listen(8000,()=>{console.log("监听8000端口")})
Express内置的中间件?
?express.json() 解析json请求体数据
const express = require('express')
const app = express()
//配置解析json的中间件
app.use(express.json())
app.post('/user',(req,res)=>{
//在服务器,通过req.body来接收客户端发送过来的请求体body
//需要配置解析表单数据的中间件,若不配置,则req.body默认为undefined
res.send('OK')
console.log(req.body)
})
app.listen(8000,()=>{console.log("监听8000端口")})
?
??express.urlencoded() 解析URL-encoded请求数据
const express = require('express')
const app = express()
//配置解析json的中间件
app.use(express.json())
//配置解析url-encoded格式的数据
app.use(express.urlencoded({extended:false}))
app.post('/user',(req,res)=>{
//在服务器,通过req.body来接收客户端发送过来的请求体body
//需要配置解析表单数据的中间件,若不配置,则req.body默认为undefined
res.send('OK')
console.log(req.body)
})
app.post('/book',(req,res)=>{
//在服务器,通过req.body来接收客户端发送过来的请求体body
//需要配置解析表单数据的中间件,若不配置,则req.body默认为undefined
res.send('OK2')
console.log(req.body)
})
app.listen(8000,()=>{console.log("监听8000端口")})
第三方中间件?
注意:Express内置的express.urlencoded()中间件,就是基于body-parser这个第三方中间件封装的
?
const express = require('express')
const app = express()
// //配置解析json的中间件
// app.use(express.json())
// //配置解析url-encoded格式的数据
// app.use(express.urlencoded({extended:false}))
//第三方中间件
const parser = require('body-parser')
app.use(parser.urlencoded({extended:false}))
app.post('/user',(req,res)=>{
//在服务器,通过req.body来接收客户端发送过来的请求体body
//需要配置解析表单数据的中间件,若不配置,则req.body默认为undefined
res.send('OK')
console.log(req.body)
})
app.post('/book',(req,res)=>{
//在服务器,通过req.body来接收客户端发送过来的请求体body
//需要配置解析表单数据的中间件,若不配置,则req.body默认为undefined
res.send('OK2')
console.log(req.body)
})
app.listen(8000,()=>{console.log("监听8000端口")})
?自定义中间件
?
?
?
?
const express = require('express')
const app = express()
//导入querystring模块
const qs = require('querystring')
//解析表单数据的中间件
app.use((req,res,next)=>{
//储存客户端发送过来的请求体数据
let str = ''
//监听req的data事件
req.on('data',(chunk)=>{
str += chunk
})
//监听req的end事件
req.on('end',()=>{
//str中是完整的请求体数据
console.log(str)
//把字符串格式的请求体数据,解析为对象格式
const body = qs.parse(str)
console.log(body)
//挂载为req属性
req.body = body
next()
})
})
app.post('/user',(req,res)=>{
res.send(req.body)
})
app.listen(8000,()=>{console.log("监听8000端口")})
custom-body.js 实现自定义函数
//导入querystring模块
const qs = require('querystring')
const bodyParser = (req,res,next)=>{
//储存客户端发送过来的请求体数据
let str = ''
//监听req的data事件
req.on('data',(chunk)=>{
str += chunk
})
//监听req的end事件
req.on('end',()=>{
//str中是完整的请求体数据
console.log(str)
//把字符串格式的请求体数据,解析为对象格式
const body = qs.parse(str)
console.log(body)
//挂载为req属性
req.body = body
next()
})
}
module.exports = bodyParser
?person.js 导入自定义函数,注册为全局中间件
const express = require('express')
const app = express()
//导入中间件模块
const customBodyParser = require('./custom-body')
//将自定义中间件函数,注册为全局中间件
app.use(customBodyParser)
app.post('/user',(req,res)=>{
res.send(req.body)
})
app.listen(8000,()=>{console.log("监听8000端口")})
|