深入理解express中间件

什么是中间件?
1 中间可以进行一些条件的判断,如果符合条件就继续执行下面的程序,否则就阻断,被拦截了,下面的程序也就不再执行[一般中间件放在get post 这个路由接口前面执行];

2 中间件就是一个函数,通过它可以执行不同的功能。我们也可以单独封装一个中间件,然后引入

3 分类:
应用程序中间件
路由中间件
异常处理中间件
内置中间件
第三方中间件


1 应用程序中间件
get请求测试:http://localhost:3356/better?name=sh&age=25

const express = require('express');

var app = express();


app.use('/',(req,res,next)=>{
    console.log("a");
    next();
})

app.use('/',(req,res,next)=>{
    console.log('b');
    next();
})

app.get('/better',(req,res)=>{
    console.log('c');
    res.send({
        code:1,
        success:200,
        data:req.query
    })
})

app.listen(3356);

本地打印结果:
a
b
c

get请求返回的结果:json格式

{
    "code":1,
    "success":200,
    "data":{
        "name":"sh",
        "age":"25"
    }
}

中间件的一些写法形式:
1 常规形式:
如上所示

2 代理参数的中间件接口(如果你需要取出数据可以通过req.params进行提取)
官方文档:
An object containing properties mapped to the named route “parameters”.
For example, if you have the route /user/:name,
then the “name” property is available as req.params.name. This object defaults to {}.

翻译:包含映射到指定的路线“参数”属性的对象。
例如,如果你有route/user/:name,那么“name”属性可作为req.params.name。
该对象默认为{}。

请求地址:
http://localhost:3356/add/name/ss/age/25 【GET请求】

const express = require('express');

var app = express();


app.use('/add/name/:name/age/:age',(req,res,next)=>{
    console.log("a");
    console.log(req.params);
    next();
})

// 这个中间件接口指向localhost 如果设置的和访问的接口不同,将会直接跳过

app.use('/',(req,res,next)=>{
    console.log('b');
    next();
})

app.get('/add/name/:name/age/:age',(req,res)=>{
    console.log('c');
    res.send({
        code:1,
        success:200,
        data:req.params
    })
})

app.listen(3356);

执行结果:
a
{ name: 'ss', age: '25' }
b
c

get请求返回的结果:{
 "code": 1,
"success": 200,
 "data": {   
"name": "ss",
    "age": "25"
  }
}

3 组合方式
http://localhost:2500/good

const express = require('express');

var app = express();

app.use('/',(req,res,next)=>{
    console.log("a"),
    next();
},(req,res,next)=>{
    console.log('b');
    next();
})

app.get('/good',(req,res)=>{
    console.log("c");
    res.send('OK');
})


app.listen(2500);

打印结果:
a
b
c

get请求返回信息: ok

2 路由中间件
1 准备: 需要下载express 以及自己需要的第三方的中间件(这里需要接受post数据,因此使用了body-parser第三方中间件)

express 和 第三方的中间件可以自行通过npm 或者 yarn 进行安装

为了更好的演示效果,本次将路由中间件单独独立出来,放在routers.js中
user.js

const express = require('express');
const userRouter = require('./routers');
const bodyParser = require('body-parser');

var app = express();

// extended设置了false 表示不采用第三方qs来处理 使用querystring来进行数据的解析,这是URL-encode解析器
app.use(bodyParser.urlencoded({extended:false}));
// 添加json解析器
app.use(bodyParser.json());

app.use('/good',userRouter);
app.listen(3356);

routers.js

const express = require('express');
var router = express.Router();


router.use('',(req,res,next)=>{
    console.log("验证");
    next();
})

router.use('/',(req,res,next)=>{
    console.log(req)
    console.log(req.body);
    if(req.body.name==="wanghao"){
        // res.send(req.body);
        next();
    }
})
router.get('/name',(req,res)=>{
    console.log("aa");
    res.send({
        result:"success"
    });
})
module.exports = router;

测试工具:
insomnia

对于上面数据如何进行接收:存在两种方式,这两种方式基于你请求的方式get or post

1 如果是get请求,你可以直接使用req.query进行获取

http://localhost:3356/good/name?name=wh&age=12
const express = require('express');
var router = express.Router();
router.use('',(req,res,next)=>{
    console.log("验证");
    next();
})
router.use('/',(req,res,next)=>{
    console.log(req.query);
    if(req.query.name==="wh"){
        next();
    }
})
router.get('/name',(req,res)=>{
    console.log(req.query);
    console.log("aa");
    res.send({
        result:"success"
    });
})
module.exports = router;
本地打印结果:
//入口打印结果
验证
//中间判断层打印结果
{ name: 'wh', age: '12' }
//get路由接口打印结果
aa
{ name: 'wh', age: '12' }

get请求返回的结果:
{ 
"result": "success"
}

if(req.query.name==="wh"){
    next();
}

})
router.get(’/name’,(req,res)=>{
console.log(req.query);
console.log(“aa”);
res.send({
result:“success”
});
})
module.exports = router;
本地打印结果:
//入口打印结果
验证
//中间判断层打印结果
{ name: ‘wh’, age: ‘12’ }
//get路由接口打印结果
aa
{ name: ‘wh’, age: ‘12’ }

get请求返回的结果:
{
“result”: “success”
}

2 如果是post请求,你需要安装第三方的中间件 body-parser 使用req.body进行解析数据
在这里插入图片描述
执行文件

const express = require('express');
const userRouter = require('./routers');
const bodyParser = require('body-parser');

var app = express();

app.use(bodyParser.urlencoded({extended:false}));
app.use(bodyParser.json());

app.use('/good',userRouter);
app.listen(3356);

封装的路由中间件

const express = require('express');
var router = express.Router();

router.use('',(req,res,next)=>{
    console.log("验证");
    next();
})

router.use('/',(req,res,next)=>{
    console.log(req.body);
    if(req.body.name==="wh"){
        next();
    }
})

router.post('/name',(req,res)=>{
    console.log(req.body);
    res.send({
        result:"success"
    });
})

module.exports = router;

执行打印结果:
验证
{ name: 'wh', age: '22' }
{ name: 'wh', age: '22' }


post请求返回结果:
{
    result:"success"
}

3 如果有一个路由中间件出现问题,会发现post请求无返回结果
在这里插入图片描述

总结:

1 通过以上两个请求测试,可以发现,get和post请求时对数据的解析方式不同,get使用req.query可以直接解析, post 需要使用req.body(这里还需要写在第三方的中间件body-parser)
2 通过第三点,我们可以看出,如果中间件出现不符合条件的数据就会停止继续执行下面的程序,因此,我们可以用中间件进行一些验证信息的判断(比如登录的用户名和密码等)
3 要注意,中间件是可以接受任何请求方式发送过来的数据,仅仅是解析数据的形式存在不同而已

3 异常处理中间件
错误优先原则
模拟测试:通过访问一个get请求抛发一个错误信息,这个信息一旦被隐藏处理中间件捕获,就会报错,并且显示出你设置的信息
router.js

const express = require('express');
var router = express.Router();

router.get('/r3',(req,res)=>{
    throw new Error('error message');
})

module.exports = router;

app.js

const express = require('express');
const router = require('./routers');

var app = express();
app.use('/user',router);

//错误优先原则 异常处理中间件
app.use((err,req,res,next)=>{
    console.log(err.stack);
    res.status(200).send('something is wrong');
    next();
})
app.listen(2300)

通过get请求访问:
http://localhost:2300/user/r3
由于异常处理中间件会捕获到,因此会显示错误提示信息,这个状态码可以自行设置,本例设置的为200在这里插入图片描述
在这里插入图片描述

4 内置中间件
exprss.static 静态资源的设置,html 图片等

express.json 解析传入的数据请求,为json格式

5 第三方中间件
https://www.expressjs.com.cn/resources/middleware.html

6 封装一个中间件

b.js
const express = require('express');
//引入封装好的中间件
const middle = require('./a');
var app = express();

// 使用封装的中间件,并且设置一个接口
app.use('/:name/age/:age',middle());

app.get('',(req,res)=>{
    console.log('aaa');
})

app.listen(2500);


a.js 利用模块封装的一个中间件
module.exports = function(){
    return function(req,res,next){
        console.log(req.params);
        res.send(req.params);
        next()
    }
}

get请求测试
http://localhost:2500/wh/age/21

get请求返回结果:
{"name":"wh","age":"21"}

本地打印结果
{ name: 'wh', age: '21' }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值