Node.js学习-day7-中间件

中间件

中间件:特指业务流程中的中间处理环节
Express的中间件,实质上就是一个function处理函数,格式如下:

//这里的function 就是中间件函数
app.get('/',function(req,res,next){
	next();
})

注意,中间件函数的形参列表中,必须包含next参数,而路由处理函数中只包含req和res.
next函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件或路由。

全局生效的中间件

客户端发起的请求,达到服务器之后,都会触发的中间件,叫做全局生效的中间件,通过调用app.use(中间件函数),即可定义一个全局生效的中间件。

const express = require('express')

const app = express()
//next()表示把流转关系转交给下一个中间件或路由,由于没有下一个中间件,因此交给了/或/user路由
const mw = function(req,res,next){
    console.log('调用了mw中间件');
    next();
}

app.use(mw)

app.get('/',(req,res)=>{
    console.log('经过/路由');
    res.send('/')
})

app.get('/user',(req,res)=>{
    console.log('经过/user路由');
    res.send('/user')
})

app.listen(80,()=>{
    console.log('http://127.0.0.1');
})

中间件的作用:多个中间件之间,共享同一份req和res。基于这样的特性,我们可以在上游的中间件中,统一为req或res对象添加自定义属性或方法,供下游的中间件或路由使用。

const express = require('express')

const app = express()

const mw = function(req,res,next){
    //在中间件中获取到达服务器的时间
    const time = Date.now()
    //挂载在req的自定义属性startTime上
    req.startTime = time;
    next();
}

app.use(mw)

app.get('/',(req,res)=>{
    //下游路由可以获取到req的自定义属性
    res.send('Home page' + req.startTime)
})

app.get('/user',(req,res)=>{
    res.send('user page' + req.startTime)
})

app.listen(80,()=>{
    console.log('http://127.0.0.1');
})

可以使用app.use()连续定义多个全局中间件,客户端到达服务器之后,会根据中间件定义的先后顺序依次进行调用。

局部生效的中间件

不适用app.use()定义的中间件,叫做局部中间件,直接把中间件名称加载路径之后即可:

const express = require('express')

const app = express()

const mw = function(req,res,next){
    console.log('调用了中间件');
    next();
}

//调用了局部中间件
app.get('/',mw,(req,res)=>{
    res.send('Home page')
})
//没有调用局部中间件
app.get('/user',(req,res)=>{
    res.send('user page')
})

app.listen(80,()=>{
    console.log('http://127.0.0.1');
})

可以通过如下两种方式,使用多个局部中间件:

app.get('/user',mw1,mw2,(req,res)=>{res.send('user page')})
app.get('/user',[mw1,mw2],(req,res)=>{res.send('user page')})

注意:一定要在路由之前注册中间件!!!

中间件的分类

  1. 应用级别的中间件:通过app.use()或app.get()或app.post(),绑定到app实例上的中间件,叫做应用级别中间件
  2. 路由级别的中间件:绑定到express.Router()实例上的中间件
  3. 错误级别的中间件:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。错误级别的中间件function函数中,必须包括4个形参(err,req,res,next)。错误级别的中间件必须放在所有的路由之后!!!
const express = require('express')

const app = express()

app.get('/',(req,res)=>{
    throw new Error('服务器内部出错');
    res.send('Home page')
})

app.use((err,req,res,next)=>{
    console.log('发生了错误:'+err.message);
    res.send('Error!'+err.message);
})


app.listen(80,()=>{
    console.log('http://127.0.0.1');
})
  1. Express内置中间件:express.static快速托管静态资源的内置中间件;express.json解析JSON格式的请求体数据;express.urlencoded解析URL-encoded格式的请求体数据;
app.use(express.json())
app.use(express.urlencoded({extended:false}))
app.post('/user',(req,res)=>{
    //在服务器,可以使用req.body这个属性,来接受客户端发送过来的请求体数据
    //默认情况下,如果不配置解析表单数据的中间件,则req.body默认等于undefined
    console.log(req.body);
    res.send('ok')
})

app.post('/book',(req,res)=>{
    console.log(req.body);
    res.send('ok')
})

  1. 第三方的中间件:按需下载导入并app.use()配置第三方中间件

自定义中间件

自己手动模拟一个类似express.urlencoded这样的中间件,来解析POST提交到服务器的数据

//custom-body-patser.js
const qs = require('querystring')

const  bodyParser = (req,res,next)=>{
 //str用来存储客户端发送过来的数据
 let str = ''
 //监听req的data事件(客户端发送过来的请求体数据)
 req.on('data',(chunk)=>{
     str += chunk
 })

 //监听req的end事件
 req.on('end',()=>{
     //str是完整请求体数据
     // querystring模块,是用来专门处理查询字符串,通过这个模块的parse()函数,可以轻松解析对象的格式
     const body = qs.parse(str)
     //解析出来的对象挂载到req.body上
     req.body = body
     next()
 })
}

module.exports = bodyParser
const express = require('express')

const app = express()

const customBodyParser  = require('./custom-body-parser.js')
app.use(customBodyParser)

app.post('/user',(req,res)=>{
    res.send(req.body)
})
app.listen(80,()=>{
    console.log('http://127.0.0.1');
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值