Node.js 入门 —— 中间件

2023-10-31

1 前言

本文内容来自bilibili 黑马程序员

2 中间件的概念

2.1 什么是中间件

中间件(middleware)特指业务流程的中间处理环节

2.2 中间件的调用流程

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

2.3 Express 中间件的格式

本质上是一个 function 处理函数
中间件函数的形参列表中,必须包含 next 参数,而路由处理函数只包含 req 和 res
next 函数是实现多个中间件连续调用的关键,它表示将流转关系流转给下一个中间件或者路由

3 express 中间件

3.1 定义中间件函数

// 定义一个最简单的中间件函数
const mw = (req, res, next) => {
  console.log('这是最简单的中间件函数');
  // 把流转关系,转交给下一个中间件或者路由
  next()
}

3.2 全局生效的中间件

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

app.use(mw)

3.3 局部生效的中间件

不使用 app.use() 定义的中间件,叫做局部生效的中间件

app.get('/user', mw, (req, res) => {})

3.4 中间件使用注意事项

  1. 除错误级别中间件外,其他类型中间件一定要在路由之前注册
  2. 客户端发送过来的请求,可以连续调用多个中间件进行处理
  3. 执行完中间件的业务代码之后,不要忘记调用 next() 函数
  4. 为了防止代码逻辑混乱,调用 next() 函数后不要再写额外的代码
  5. 连续调用多个中间件时,多个中问件之间,共享 req 和 res 对象

3.5 中间件的分类

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

  1. 应用级别的中间件
    通过 app.use() 、 app.get() 、 app.post() ,绑定到 app 实例上的中间件
// 应用级别的中间件(全局中间件)
app.use((req, res, next) => {
  next()
})
// 应用级别的中间件(局部中间件)
app.get('/', mw, (req, res) => {
  res.send('Hone Npage.')
})
  1. 路由级别的中间件
    绑定到 express.Router() 上的中间件
const app = express()
const router = express.Router()
// 路由级别的中间件
router.use(function (req, res, next) {
  console.log( "Time:" Date.now())
  next()
})
app.use(router)
  1. 错误级别的中间件
    作用:专门用来捕获整个项目中发生的异常错误,从而防止项目异常崩溃的问题
    格式:错误级别中间件的 function 处理函数中,必须有 4 个形参,形参顺序从前到后,分别是 (err, req, res, next)
app.get('/', (req, res) => {
  throw new Error('服务器发生错误')
  res.send('Home Page')
})
app.use((err, req, res, next) => {
  console.log('发生了错误!', err.message);
  res.send(`发生了错误!${err.message}`)
})
  1. Express 内置的中间件
  • express.static() :快速托管静态资源
  • express.json() :解析 JSON 格式的请求数据
  • express.urlencoded() :解析 URL-encoded 格式的请求数据
  1. 第三方的中间件
    非 express 官方提供的,而是由第三方开发出来的中间件

4 自定义中间件

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

实现步骤:

  1. 定义中间件
  2. 监听 req 的 data 事件
  3. 监听 req 的 end 事件
  4. 使用 querystring 模块解析请求体数据
  5. 将解析出来的数据对象挂载为 req.body
  6. 将自定义中间件封装成模块

custom-bodyparser.js

const qs = require('querystring') 

const bodyParser = (req, res, next) => {
  let str = ''
  req.on('data', (chunk) => {
    str += chunk
  })
  req.on('end', () => {
    req.body = qs.parse(str)
    next()
  })
}

module.exports = bodyParser

index.js

const express = require('express')
const bodyParser = require('./custom-bodyparser') 
const app = express()

app.use(bodyParser)

app.post('/user', (req, res) => {
  res.send(req.body)
})

app.listen(80, () => {
  console.log('http://127.0.0.1');
})
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Node.js 入门 —— 中间件 的相关文章

随机推荐

  • 引入并使用Element

    引入并使用Element 开发工具与关键技术 MVC 作者 汤池 撰写时间 2022 4 7 1 首先需要打开DW软件 新建一个html网页 然后保存到一个文件夹当中 2 然后打开element官网 下载使用Element必须引用的脚本文件
  • 2022/1/22记录网页

    65条消息 102 bert词向量进行文本分类和命名实体识别 u012416045的博客 CSDN博客 bert文本识别https blog csdn net u012416045 article details 88373965 Bert
  • 记一次kafka无法生产发送消息排查经历

    参考 欢迎点击原文 https stackoverflow com questions 37902167 kafka error while fetching metadata with correlation id leader not
  • c语言中简单变量必须,C语言规定,简单变量做实参时,它和对应形参之间的数据传递方式是()。 (A)地址传递 (B)单向值传递 (C)由...

    参考答案如下 语言规应形C由一般来说 各种调查报告在结构上都可分成哪几个部分 定地址B单演示PPT的结尾部分一般建议展示以下内容 通过startService再次启动Service时 简单间不会再执行onCreate 函数 变量蛋白质分子的
  • 图机器学习课程笔记7

    维生素C吃多了会上火 个人CSDN博文目录 cs224w 图机器学习 2021冬季课程学习笔记集合 目录 思维大纲 中文笔记 思维大纲 中文笔记
  • 树莓派入门教程 - 0 - 准备篇 - 0.3 树莓派串口访问终端

    电脑需要提前安装的工具 SSH 串口 终端神器 MobaXterm 官网下载链接 https mobaxterm mobatek net download html 使用到的硬件 USB转TTL模块 CH340 和 CP2102均可 CP2
  • 1.2-知识图谱有什么用?

    知识图谱经过几年的发展已经得到广泛的应用 当知识图谱遇上人工智能 更加突显出了它的优势和价值 最先应用于搜索 最典型的就是在谷歌搜索引擎里面应用 谷歌是在2012年率先提出来知识图谱的概念 提出这个概念的最主要的目的就是用于改善它的搜索引擎
  • ospf小结

    ospf卡住的原因 route id相同 认证不通过 区域ID不同 特殊区域标示不一致 优先级都为0 无法选举 MTU值不匹配 包的交互不完整 网络中丢包等 LSA加载不完全 hello包时间不一致 MA网络掩码不一致 虚链路建邻ABR的两
  • JVM常量池最全详解-常量池/运行时常量池/字符串常量池/基本类型常量池,看这一篇就够了

    JVM常量池最全详解 常量池 运行时常量池 字符串常量池 基本类型常量池 看这一篇就够了 常量池详解 1 字面量和符号引用 1 1 字面量 1 2 符号引用 2 常量池vs运行时常量池 3 常量池 静态常量池 4 运行时常量池 5 字符串常
  • Introduction to Scientific Programing and Simulation Using R chapter 04 答案

    strong span style font size 32px Ex1 span strong span style color 33cc00 programe cha4 6 ex1 img src https img blog csdn
  • h-a-p-p-e-n-before原则的理解

    happen before 可真是一个经典又老生常谈的话题 规则一共就八条 但看起来总有种抓不住重点的感觉 今天再整理一下对这八条规则的理解 首先我的理解是 happen before 的语义与在什么什么之前发生完全没有关系 其语义是如果
  • 网络安全实验室 综合关 解析

    网站地址 http hackinglab cn ShowQues php type pentest 第一关 渗透测试第一期 先看看 登录界面 发现可以注册和忘记密码 忘记密码可以重置密码 思路如下 重置admin密码 发现 不能直接重置密码
  • 【赠书活动|第四期《互联网广告系统:架构、算法与智能化》】

    文章目录 内容简介 作者简介 读者对象 大咖推荐 抽奖方式 本期中奖者 广告平台的建设和完善是一项长期工程 例如 谷歌早于2003年通过收购Applied Semantics开展Google AdSense 项目 而直到20年后的今天 谷歌
  • sql连接查询

    sql连接查询 单表查询 student表 select 列名 from 表名 查看全表 SELECT FROM student 可以匹配为全选 在student表中查找赵六的信息 SELECT FROM student WHERE sna
  • 插入时出现MyBatisSystemException: nested exception is

    检查完xml文件没错后 还是出现错误 org mybatis spring MyBatisSystemException nested exception is org apache ibatis binding BindingExcept
  • SourceInsight4.0黑色背景主题

    SourceInsight4 0黑色背景主题 在网上找了一通花了好多积分最后发现只改了代码区 左右代码索引文件列表和函数调用关系图都还是白底 最后自己在设置里面找了找 发现在这个版本中SI已经内置了一些常用的主题配色 先放效果图 设置在这里
  • JAVA设计模式(21) —装饰(Decorator)模式

    定义 动态的给一个对象添加一些额外的职责 就增加功能来说 Decorator模式相比生成子类更为灵活 类型 对象结构型模式 别名 包装模式 Wrapper 类图 Decorator装饰模式是一种结构型模式 它主要是解决 过度地使用了继承来扩
  • Python3实现通过HTTP协议进行文件上传及下载

    要实现这个功能 你需要在主机A上编写一个Python程序 该程序监听HTTP上传请求并处理上传的文件 同时 在主机B上 你可以使用任何支持HTTP POST请求的工具 如curl或浏览器插件 上传文件 以下是一个简单的实现示例 在主机A上的
  • Python opencv学习-4在图片上用鼠标绘制矩形区域、绘制矩形框、曲线等

    程序功能鼠标按下 拖拽生成矩形框 缺陷 拖过的区域涂黑 而且不彻底 后期换写法测试 基本逻辑 鼠标按下松开 获取坐标 绘制矩形等 未看明白如何获取到的初始坐标和结束坐标 x y从哪获取的值 import numpy as np import
  • Node.js 入门 —— 中间件

    文章目录 1 前言 2 中间件的概念 2 1 什么是中间件 2 2 中间件的调用流程 2 3 Express 中间件的格式 3 express 中间件 3 1 定义中间件函数 3 2 全局生效的中间件 3 3 局部生效的中间件 3 4 中间