中间件-理解 express中间件 路由级中间件

30 篇文章 0 订阅

中间件-理解

express而言,中间件是它的一个非常重要的概念,掌握中间件的思想对于理解学习express,提升编程水平都有很大的帮助。

生活中的中间件

一道复杂的任务拆分成几个小步骤:

  • 步骤1
  • 步骤2
  • 步骤3

我们可以称其中的每一个处理环节就是一个中间件。

招程序员的流程

  • 面试
    • hr
    • 技术
    • 综合
  • 背调(背景调查),委托第三方的公司去做背调。
  • 发offer
  • 体检
  • 入职-签合同
  • 转正
  • 离职

express中间件

中间件是一个特殊的url地址处理函数

  • 中间件是 express 的最大特色,也是最重要的一个设计。Express是一个自身功能极简,完全是路由中间件构成一个web开发框架:从本质上来说,一个Express应用就是在调用各种中间件
  • 一个 express 应用,就是由许许多多的中间件来完成的

作用

  • 执行任何代码。
  • 修改请求和响应对象。
  • 终结请求-响应循环(结束请求)。
  • 调用堆栈中的下一个中间件
    在这里插入图片描述

分类

  • 应用级中间件 app.use(express.static('public'))
  • 路由级中间件 app.get('请求路径',(req,res,next)=>{})
  • 错误处理中间件
  • 内置中间件app.use(express.static('public'))
  • 第三方中间件
  const multer = require('multer')
  app.post("/postfile",upload.single('cover'), function(req,res){
      // req.file 记录了文件上传的信息
      // req.body 记录了其它普通参数(非文件)的信息
  	// 其它操作
    res.send({msg: 'pk'})
  })

中间件-格式及基本示例

中间件本质就是一个函数,它被当作 app.use(中间件函数) 的参数来使用,或者是某个路由处理函数中使用。

1.定义格式

// 具名函数格式:
const handler1 = (req, res, next) => {
  console.log(Date.now());
  next();
}
app.use(handler1);



// 匿名函数格式:
app.use((req, res, next) => {
  console.log(Date.now());
  next();
});

说明: 中间件函数中有三个基本参数,reqresnext

  • req就是请求相关的对象,它和下一个中间件函数中的req对象是一个对象
  • res就是响应相关的对象,它和下一个中间件函数中的res对象是一个对象
  • next:它是一个函数,调用它将会跳出当前的中间件函数,执行后续中间件;如果不调用next,也不执行res.end,则整个请求都会在当前中间件卡住。

2.示例

const express = require('express')
const app = express();

app.use((req, res, next) => {
  console.log("第1个中间件");
  req.a1 = 100;
  next();
});

app.use((req, res, next) => {
  console.log("第2个中间件");
  res.setHeader('content-type', 'text/html;charset=utf8');
  res.a2 = 200;
  next();
});

app.use((req, res, next) => {
  console.log("第3个中间件");
  req.a3 = 300;
  console.log(req.a1,req.a2)
  res.end('中间件');
});


app.listen(3000,()=>{
    console.log('express应用在3000端口启动了'); 
})
  • 多个中间件先后顺序。
  • 注意通过req来附加额外的信息。
  • 如果不用next(),则不会进入下一个中间件。

3.执行流程

在这里插入图片描述

中间件-四种匹配规则

  • app.use(中间件)是应用级中间件,所有的请求都能匹配
  • app.use('/apiname',中间件) 。匹配请求路径是/apiname的请求。
  • app.get('/apiname',中间件) 。匹配get类型并且请求路径是/apiname的请求,就是我们前面说的路由
  • app.get('/apiname',中间件1,中间件2)。一个路由中使用多个中间件

中间件的应用-访问日志

模拟日志功能:你是后端程序员,你写代码去记录所有用户在哪个时间点访问了哪个页面?

function getClientIp(req) {
  return req.headers['x-forwarded-for'] ||
      req.connection.remoteAddress ||
      req.socket.remoteAddress ||
      req.connection.socket.remoteAddress;
}

app.use((req,res,next) => {
  console.log('我来用记录访问日志')
  // 获取当前用户访问的页面地址: req.url
  // 获取当前用户的id的地址: ?
  // 当前时间
  const dt = new Date()
  console.log(dt.toLocaleTimeString())
  console.log(req.url)
  console.log('来自:', getClientIp(req));

  // fs写入某个日志文件中
  next();
})

路由级中间件

使用场景

接口数量较多时,代码不好管理。以大事件的代码为例,我们定义了管理员角色的接口和普通游客的接口,这些接口如果全写在一个入口文件中(如下只是显示了4个接口,如果是40个接口,就会很难读了),也不好维护的。

const express = require('express');

const app = express();
// 两种用户的操作,对应不同的接口
app.get('/getfrontdetail', (req, res) => {
  res.send('获取游客详情');
});

app.get('/getfrontinfo', (req, res) => {
  res.send('获取游客信息');
});

// 两种用户的操作,对应不同的接口
app.get('/getadmincate', (req, res) => {
  res.send('管理员获文章类别信息');
});

app.get('/getadmininfo', (req, res) => {
  res.send('获取管理员信息');
});

app.listen(3000, () => {
  console.log(3000);
});

我们的目标就是把它们拆开到不同的文件中,以便于管理。

思路

第一步 整理 分类

整理接口名。对众多的接口名进行整理和分类,以一级目录,二级目录这样的方式进行。例如:

/admin/getcate 
/admin/getinfo
/front/getinfo
/front/getdetail

第二步 分模块 定义 导出

通过nodejs的模块化,分模块定义路由中间件,并导出

第三步 主入口文件 导入使用

主文件中导入并使用路由中间件。

步骤

第一步:定义两个模块(两个js文件)。分别保存不同的分类的接口。

- front.js
- server.js
// ./router/front.js
const express = require('express');
const router = express.Router();
router.get('/getinfo', function(req, res) {
  res.send('getinfo');
});
router.get('/getdetail', function(req, res) {
  res.send('getdetail');
});
module.exports = router;
// ./router/server.js
const express = require('express');
const router = express.Router();

router.get('/getinfo', function(req, res) {
  res.send('管理员getinfo');
});
router.get('/getdetail', function(req, res) {
  res.send('管理员getdetail');
});
module.exports = router;

注意: 上面epxress.Router()的用法。

第二步:在主入口文件中使用它们

const express = require('express');
const app = express();

const frontRouter = require('./router/front');
const serverRouter = require('./router/admin');

app.use('/front', frontRouter);
app.use('/server', serverRouter);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值