Express:Express 中间件

news2024/12/24 20:44:57

中间件的概念

1. 什么是中间件

中间件(Middleware ),特指业务流程中间处理环节

2. 现实生活中的例子

在处理污水的时候,一般都要经过三个处理环节,从而保证处理过后的废水,达到排放标准。

处理污水的这三个中间处理环节,就可以叫做中间件。

3. Express 中间件的调用流程

当一个请求到达 Express 的服务器之后,可以连续调用多个中间件,从而对这次请求进行预处理

 4. Express 中间件的格式

Express 的中间件,本质上就是一个 function 处理函数Express 中间件的格式如下:

注意:中间件函数的形参列表中,必须包含 next 参数。而路由处理函数中只包含 req res

5. next 函数的作用

next 函数是实现多个中间件连续调用的关键,它表示把流转关系转交给下一个中间件路由

 Express 中间件的初体验

1. 定义中间件函数

可以通过如下的方式,定义一个最简单的中间件函数:

2. 全局生效的中间件

客户端发起的任何请求,到达服务器之后,都会触发的中间件,叫做全局生效的中间件。

通过调用 app.use(中间件函数),即可定义一个全局生效的中间件,示例代码如下:

 3. 定义全局中间件简化形式

必须要有next()不然只是调用了中间件函数,却没有将它流传下去 

 4. 中间件的作用

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

5. 定义多个全局中间件

可以使用 app.use() 连续定义多个全局中间件。客户端请求到达服务器之后,会按照中间件定义的先后顺序依次进行调用,示例代码如下:

不使用中间件,如果有需求,获取路由到服务器的时间,我们这么写,代码的重复率太高了,而此时我们可以挂载到中间件中,因为中间件可以传递到下面

6. 局部生效的中间件

不使用 app.use() 定义的中间件,叫做局部生效的中间件,示例代码如下:

 7. 定义多个局部中间件

可以在路由中,通过如下两种等价的方式,使用多个局部中间件

 如果有全局中间件和局部中间件,会先调用全局

8. 了解中间件的5使用注意事项

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

客户端发送过来的请求,可以连续调用多个中间件进行处理

执行完中间件的业务代码之后,不要忘记调用 next() 函数

next函数主要负责将控制权交给下⼀个中间件,如果当前中间件没有终结请求,并且next没有被调⽤,那么请求将被挂起,后边定义的中间件将得不到被执⾏的机会

为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码

连续调用多个中间件时,多个中间件之间,共享 req res 对象

中间件的分类

为了方便大家理解记忆中间件的使用,Express 官方把常见的中间件用法,分成了 5 大类,分别是:

应用级别的中间件

路由级别的中间件

错误级别的中间件

Express 内置的中间件

第三方的中间件

1. 应用级别的中间件

通过 app.use() app.get() app.post() 绑定到 app 实例上的中间件,叫做应用级别的中间件,代码示例如下:

2. 路由级别的中间件

绑定到 express.Router() 实例上的中间件,叫做路由级别的中间件。它的用法和应用级别中间件没有任何区别。只不过,应用级别中间件是绑定到 app 实例上路由级别中间件绑定到 router 实例上,代码示例如下:

 3. 错误级别的中间件

错误级别中间件的作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题。

格式:错误级别中间件的 function 处理函数中,必须有 4 个形参,形参顺序从前到后,分别是 (err, req, res, next)

注意:错误级别的中间件,必须注册在所有路由之后

崩溃了

 错误的消息

要放在所有路由后面 

4. Express内置的中间件

Express 4.16.0 版本开始,Express 内置了 3 常用的中间件,极大的提高了 Express 项目的开发效率和体验:

express.static 快速托管静态资源的内置中间件,例如: HTML 文件、图片、CSS 样式等(无兼容性)

express.json 解析 JSON 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)

如果没有配置json解析,那么返回的是 undefined

这样就拿到了 

express.urlencoded 解析 URL-encoded 格式的请求体数据(有兼容性,仅在 4.16.0+ 版本中可用)

 没有解析的传入的是空对象

 app.use(express.urlencoded({extended:false}))固定写法

extended:false的意思是:不使用第三方的解析方式,只使用自身的解析方式;如果是true就使用第三方解析方式

5. 第三方的中间件

Express 官方内置的,而是由第三方开发出来的中间件,叫做第三方中间件。在项目中,大家可以按需下载配置第三方中间件,从而提高项目的开发效率。

例如:在 express@4.16.0 之前的版本中,经常使用 body-parser 这个第三方中间件,来解析请求体数据。使用步骤如下:

运行 npm install body-parser 安装中间件

使用 require 导入中间件

调用 app.use() 注册并使用中间件

 注意:Express 内置的 express.urlencoded 中间件,就是基于 body-parser 这个第三方中间件进一步封装出来的。

自定义中间件

1. 需求描述实现步骤

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

实现步骤:

定义中间件

监听 req data 事件

监听 req end 事件

使用 querystring 模块解析请求体数据

将解析出来的数据对象挂载为 req.body

将自定义中间件封装为模块

2. 定义中间件

使用 app.use() 来定义全局生效的中间件,代码如下:

3. 监听 req data 事件

在中间件中,需要监听 req 对象的 data 事件,来获取客户端发送到服务器的数据。

如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后分批发送到服务器。所以 data 事件可能会触发多次,每一次触发 data 事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接。

 4. 监听 req end 事件

当请求体数据接收完毕之后,会自动触发 req end 事件。

因此,我们可以在 req end 事件中,拿到并处理完整的请求体数据。示例代码如下:

5. 使用 querystring 模块解析请求体数据

Node.js 内置了一个 querystring 模块,专门用来处理查询字符串。通过这个模块提供的 parse() 函数,可以轻松把查询字符串,解析成对象的格式。示例代码如下:

 6. 将解析出来的数据对象挂载为 req.body

上游中间件下游中间件及路由之间,共享同一份 req res。因此,我们可以将解析出来的数据,挂载为 req 的自定义属性,命名为 req.body,供下游使用。示例代码如下:

 这里要注意一定要在end事件使用next()引流下去 

7. 将自定义中间件封装为模块

为了优化代码的结构,我们可以把自定义的中间件函数,封装为独立的模块,示例代码如下:

对自定义的中间件模块化拆分

// 导入express模块
const express=require('express')
// 创建express的服务器实例
const app=express()
//1.导入自己封装的中间件模块
const customBodyParser=require('./14.custom-body-parser')
// 2.将自定义的中间件函数,注册为全局可用的中间件
app.use(customBodyParser)
app.post('/user',(req,res)=>{
    res.send(req.body)
 })


// 调用app.listen方法,指定端口号并启动web服务器
app.listen('80',()=>{
    console.log('http://127.0.0.1');
})

custom-body-parser

// 导入Node.js 内置的querystring模块
const qs=require('querystring')
const bodyParser=(req,res,next)=>{
    // 定义中间件具体的业务逻辑
    // 1.定义一个str字符串,专门用来存储客户端发送过来的请求体数据
    let str="";
    // 2.监听req.data事件
    req.on('data',(a)=>{
        str+=a;
    })
    // 3.监听req的end事件
    req.on("end",()=>{
        // 在str中存放的是完整的请求体数据
        // console.log(str);
        // 把字符串格式的请求体数据,解析成对象格式

        const body=qs.parse(str)
        req.body=body
        next()
    })
}

module.exports=bodyParser

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/46451.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

aws cloudformation 堆栈集的创建和使用

资料 使用 AWS CloudFormation StackSets 跨多个 AWS 账户和区域配置资源AWS cloudformation示例模板堆栈集堆栈实例状态原因 很多组织使用大量的 AWS 账户,通常用 AWS Organizations 将这些账户组织为分层结构,分组为不同的组织部门 (OU)。并且希望确…

Teams app 的 SSO 机制

我们来继续我们的 Teams sample 之旅,上一个讲了 Tab app,那我们这里再深入一步,看一下如何使用 sso 机制。 sso 是一个很有用机制,它可以让我们的 teams app 能获取当前用户的身份。sso 很多时候比较难彻底理解,在开…

刷爆力扣之公平的糖果交换

刷爆力扣之公平的糖果交换 HELLO,各位看官大大好,我是阿呆 🙈🙈🙈 今天阿呆继续记录下力扣刷题过程,收录在专栏算法中 😜😜😜 该专栏按照不同类别标签进行刷题&#xff…

【数据链路层】循环冗余码CRC、后退N帧协议GBN、选择重传协议SR、CSMA/CA

文章目录循环冗余码CRC多帧滑动窗口连续ARQ协议后退N帧协议GBN选择重传协议SRCSMA/CA---针对无线局域网处理隐蔽站问题RTS,CTS循环冗余码CRC /*** 计算CRC16校验码** param bytes* return* [1,3,4,1,205,1,18,235,173]*/public static String CRC16(byte[] bytes) {…

终于见识到了微服务的天花板!SpringCloud全线手册,太强了

后台都是在问微服务架构的面试题怎么答,想聊聊微服务架构了。微服务架构一跃成为 IT 领域炙手可热的话题也就这两年的事,大量一线互联网公司因为庞大的业务体量和业务需求,纷纷投入了微服务架构的建设中,像阿里巴巴、百度、美团等…

Kamiya丨Kamiya艾美捷大鼠微量白蛋白酶联免疫吸附试验说明书

Kamiya艾美捷大鼠微量白蛋白酶联免疫吸附试验预期用途: 大鼠微量白蛋白酶联免疫吸附试验(ELISA)是一种高灵敏度的双位点酶联免疫吸附试验(ELISA)大鼠生物样品中微量白蛋白的测定。仅供研究使用。 引言 白蛋白&#x…

Java项目:ssm学生学籍管理系统

作者主页:源码空间站2022 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 SSM项目-学生学籍管理系统。该项目分管理员、老师、学生三种用户角色。每种角色分别对应不同的菜单; 以下分别介绍各个角色对应的功…

[附源码]计算机毕业设计springboot基于Java的日用品在线电商平台

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

二进制数据的贝叶斯非参数聚类算法(Matlab代码实现)

目录 💥1 概述 📚2 部分运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 利用图像结构信息是字典学习的难点,针对传统非参数贝叶斯算法对图像结构信息利用不充分,以及算法运行效率低下的问题,该文…

GoLand2022.2.5版本Hello调动Greetings包

安装Goland2022.2.5 版本 1.官网下载goland-2022.2.5.dmg版本(Mac)版本。如果是windows版本也可以直接下载) 2.配置gopath,基本都是配置.我这里配置为/usr/local/go 作为全目录,如果是windows,直接在环境中配置path路…

Mysql基础知识篇(二)

1.UNION 与 UNION ALL 的区别? 如果使用 UNION,会在表链接后筛选掉重复的记录行如果使用 UNION ALL,不会合并重复的记录行从效率上说,UNION ALL 要比 UNION 快很多,如果合并没有刻意要删除重复行,那么就使…

自动化测试框架

自动化测试框架1.自动化测试框架核心功能1.数据驱动2.页面驱动3.关键字驱动2.关键字驱动实现-文档形式3.关键字驱动实现-表格形式1.自动化测试框架核心功能 这三种驱动测试可以结合使用来完成系统的自动化测试。可以将测试数据 1.数据驱动 将测试代码和测试数据分离&#xff…

科技云报道:云计算走向工业互联网“深水区”

科技云报道原创。 在新科技革命中,将网格化、信息化与智能化深度融合的工业互联网,正在将人、机、物全面互联,实现全要素、全产业链、全价值链的连接,推动传统产业加快转型升级、助力新兴产业加速发展壮大。 工业如何在快速变革…

培训机构借助创客匠人发力线上业务

疫情反反复复,传统线下教学受到严重影响,转型线上、借力线上发展业务成为行业主流趋势。但是,没有线上经验,人手不足的线下教培机构是否可以转型线上做教学服务,实现招生引流呢? 答案是——可以!用对工具,选对模式,其实很简单! 有很多没有专门线上运营团队,甚至是…

《计算机体系结构量化研究方法》1.7 可信任度

主要内容 计算机是在不同的抽象层上设计和构造的。我们可以逐级深入计算机的不同层面,将每个组件放大为一个完整的子系统进行查看,直到深入到独立的晶体管为止。尽管有些故障会波及整个系统,比如掉电,但许多故障可以被限制在模块…

leetcode-每日一题-1758-生成交替二进制字符串的最少操作数(简单,数学思想)

这道题标记为简单题是正常的,因为当你想到0或者1开头的时候就已经结束了看看我的分析 那么知道这个信息之后就很简单了,加上我们的位运算符号^作为标记即可,大家看看代码实现 1758. 生成交替二进制字符串的最少操作数 难度简单88收藏分享切换…

R语言和Tableau通过情感分析,我们可以从特朗普的推文得到什么?

社交媒体分析的许多用途中的一些是情绪分析,我们评估特定问题的帖子是积极还是消极。我们把社交媒体分析、机器学习、预测建模等集成到文本数据挖掘中。最近我们被客户要求撰写关于推文的研究报告,包括一些图形和统计输出。 在这篇文章中,我…

使用React.ts创建一个密码生成器的简单示例

目录密码生成器DemoFeature知识点React TypeScript —— Function Components为元素(::before/::after)绑定点击事件React如何正确定义对象数组在React中设置复选框check属性三目运算符实现React动态绑定class和style参考资料密码生成器Demo 使用密码生成器工具创建随机密码。P…

Java基于springboot +vue网上超市购物网站 多商家

随着我国信息化的发展,大家更多的是希望通过网络获取到更多的直接所需的信息,而商品一直以来就是人类永恒的追求之一,如何能够享有到更多的商品是很多人一直以来关系的问题。 本系统通过在线网购的方式让用户可以在需要购买商品但是有没有时间…

git submodule创建子仓库

git submodule创建子仓库 文章目录git submodule创建子仓库简介创建主仓库创建子仓库将子仓库添加到主仓库中将合并后的主仓库提交推送到云端简介 当我们的项目伴随着时间的增长越来越大的时候,单一的仓库便不再方便管理,这时候就需要将部分功能提取出来…