自定义中间件
1.使用 app.use0来定义全局生效的中间件
// 导入 express 模块
const express = require('express')
// 创建 express的服务器实例
const app = express()
app.use(function(req, res, next) {// 中间件的业务逻辑
})
2.监听 req 的 data 事件
在中间件中,需要监听 req 对象的 data 事件,来获取客户端发送到服务器的数据
如果数据量比较大,无法一次性发送完毕,则客户端会把数据切割后,分批发送到服务器。所以 data 事件可能会触发多次,每一次触发 data 事件时,获取到数据只是完整数据的一部分,需要手动对接收到的数据进行拼接。
app.use(function(req, res, next) {// 中间件的业务逻辑//定义变量,用来存储客户端发送过来的请求体数据let str = ''// 监听 req 对象的 data 件 (客户端发送过来的新的请求体数据)req.on('data',(chunk) => (拼接请求体数据,隐式转换为字符串str += chunk})
})
3.监听req 的end 事件
当请求体数据接收完毕之后,会自动触发 req的end 事件
因此,我们可以在 req 的 end 事件中,拿到并处理完整的请求体数据。示例代码如下:
app.use(function(req, res, next) {// 中间件的业务逻辑//定义变量,用来存储客户端发送过来的请求体数据let str = ''// 监听 req 对象的 data 件 (客户端发送过来的新的请求体数据)req.on('data',(chunk) => (拼接请求体数据,隐式转换为字符串str += chunk})// 监听 req 对象的 end 事件 (请求体发送完毕后自动触发)req.on( 'end', () => (// 打印完整的请求体数据console.log(str)// TODO: 把字符串格式的请求体数据,解析成对象格式})
})
4.使用querystring 模块解析请求体数据
Node.js 内置了一个 querystring 模块,专门用来处理查询字符串。通过这个模块提供的 parse() 函数,可以轻松把查询字符串,解析成对象的格式。示例代码如下:
// 导入处理 querystring 的 Node.js 内置模块
const qs = require( 'querystring' )
app.use(function(req, res, next) {// 中间件的业务逻辑//定义变量,用来存储客户端发送过来的请求体数据let str = ''// 监听 req 对象的 data 件 (客户端发送过来的新的请求体数据)req.on('data',(chunk) => (拼接请求体数据,隐式转换为字符串str += chunk})// 监听 req 对象的 end 事件 (请求体发送完毕后自动触发)req.on( 'end', () => (// 打印完整的请求体数据// TODO: 把字符串格式的请求体数据,解析成对象格式// 调用 qs.parse() 方法,把查询字符串解析为对象const body = qs.parse(str)console.log(body)})
})
5.将解析出来的数据对象挂载为 req.body
上游的中间件和下游的中间件及路由之间,共享同一份 req 和 res。因此,我们可以将解析出来的数据,挂载为 req的自定义属性,命名为 req.body,供下游使用。示例代码如下:
// 导入处理 querystring 的 Node.js 内置模块
const qs = require( 'querystring' )
app.use(function(req, res, next) {// 中间件的业务逻辑//定义变量,用来存储客户端发送过来的请求体数据let str = ''// 监听 req 对象的 data 件 (客户端发送过来的新的请求体数据)req.on('data',(chunk) => (拼接请求体数据,隐式转换为字符串str += chunk})// 监听 req 对象的 end 事件 (请求体发送完毕后自动触发)req.on( 'end', () => (// 打印完整的请求体数据// TODO: 把字符串格式的请求体数据,解析成对象格式// 调用 qs.parse() 方法,把查询字符串解析为对象const body = qs.parse(str)console.log(body)req.body = bodynext()})
})
6.将自定义中间件封装为模块
为了优化代码的结构,我们可以把自定义的中间件函数,封装为独立的模块,示例代码如下:
// middleware.js模块中的代码
const qs = require('querystring')
function bodyParser(req, res, next){ /*省略其它代码*/ }
module.exports = bodyParser // 向外导出解折请求体数据的中间件函数
// ---------------分割线--------------
//1,导入自定义的中间件模块
const myMiddleware = require( 'middleware' )
// 2,注朋自定义的中间件模块
app.use(myMiddleware)
相关文章:
自定义中间件
1.使用 app.use0来定义全局生效的中间件 // 导入 express 模块 const express require(express) // 创建 express的服务器实例 const app express() app.use(function(req, res, next) {// 中间件的业务逻辑 }) 2.监听 req 的 data 事件 在中间件中,需要监听 re…...
优化机器学习:解析数据归一化的重要性与应用
在机器学习中,数据归一化是一种数据预处理的技术,旨在将数据转换为相似的范围或标准化的分布。这样做的主要目的是消除不同特征之间的量纲差异或数值范围差异,以确保模型在训练时更稳定、更有效地学习特征之间的关系。 通常,机器…...
五分钟,Docker安装flink,并使用flinksql消费kafka数据
1、拉取flink镜像,创建网络 docker pull flink docker network create flink-network2、创建 jobmanager # 创建 JobManager docker run \-itd \--namejobmanager \--publish 8081:8081 \--network flink-network \--env FLINK_PROPERTIES"jobmanager.rpc.ad…...
【小聆送书第一期】让架构师的成神之路温暖你这个不景气的冬天
🌈个人主页:聆风吟 🔥系列专栏:网络奇遇记、数据结构 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言 书籍一览 ⛳️书籍一⛳️书籍二⛳️书籍三⛳️书籍四⛳️书籍五⛳️书籍六⛳️书…...
网页爬虫反扒措施有哪些?
爬虫之常见的反扒 cookies 一般用requests直接请求网址的时候有时候可能会遇到反扒措施,这时候可以考虑一下加上user-agent伪装成浏览器;也可能有登录限制,这时候cookies就有用处了 浏览器中的cookie是保存我们的账号数据和访问记录&#…...
C#实现批量生成二维码
相信大家都使用过草料二维码生成器,单独生成二维码可以,但是批量生成二维码就需要收费了。既然要收费,那就自己写一个。 接口采用导入Excel文件生成二维码,首先需要读取Excel的数据,方法如下所示: /// <…...
3种在ArcGIS Pro中制作山体阴影的方法
山体阴影可以更直观的展现地貌特点,表达真实的地形,这里为大家介绍一下在ArcGIS Pro中制作山体阴影的方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的DEM数据,除了DEM数据,常见的GIS数据…...
【ChatGLM2-6B】Docker下部署及微调
【ChatGLM2-6B】小白入门及Docker下部署 一、简介1、ChatGLM2是什么2、组成部分3、相关地址 二、基于Docker安装部署1、前提2、CentOS7安装NVIDIA显卡驱动1)查看服务器版本及显卡信息2)相关依赖安装3)显卡驱动安装 2、 CentOS7安装NVIDIA-Doc…...
输入两个整数,输出它们的乘积。 ← Python 及 C++ 代码比较
【题目描述】 输入两个整数,输出它们的乘积。【Python代码】 x,ymap(int,input().split()) print(x*y) 【C代码】 #include<bits/stdc.h> using namespace std;int x,y; int main() {cin>>x>>y;cout<<x*y<<endl;return 0; }/* in:…...
C语言——从键盘输人一个表示年份的整数,判断该年份是否为闰年,并显示判断结果。
#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int year 0;printf("请输入年份:");scanf("%d",&year);if((year%4 0) && (year%100!0) || (year%400 0)){printf("%d是闰年\n",year);}else{p…...
出于隐私和安全的考虑,有时需要从谷歌删除你的个人数据,有两种方法
如果你是公众人物、企业或拥有个人品牌的人,那么拥有在线形象很重要。然而,你可能会发现,通过谷歌搜索,陌生人可以获得你的个人信息,如联系方式、地址和财务信息,这会让你感到不安。 幸运的是,…...
【同一局域网下】两台电脑之间互ping
两台电脑互ping 首先需要连接同一网咯关闭需要ping的电脑的防火墙 关闭防火墙步骤(以win11系统为例): 设置 --> 隐私和安全性 --> Windows 安全中心 打开Windows安全中心 防火墙和网络保护 --> 选择正在使用的网络 关闭 ping其他…...
【精选】Ajax技术知识点合集
Ajax技术详解 Ajax简介 Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建 交互式、快速动态应用的网页开发技术,无需重新加载整个网页的情况下,能够更新页面局 部数据的技术。通过在…...
智能优化算法应用:基于水循环算法无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于水循环算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于水循环算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.水循环算法4.实验参数设定5.算法结果6.参考文献7.…...
java-netty知识点笔记和注意事项
如何获取ctx的id 使用ctx.ctx.toString()就可以了 public void channelRead(ChannelHandlerContext ctx, Object msg) {//传来的消息包装成字节缓冲区String byteBuf (String) msg; // ByteBuf byteBuf (ByteBuf) msg;//Netty提供了字节缓冲区的toString方法ÿ…...
英伟达不同系列GPU介绍
英伟达有以下几个系列的产品线,并介绍它们的特点和主要应用领域: 1. GeForce系列(G系列): - 特点:GeForce系列是英伟达主打的消费级GPU产品线,注重提供高性能的图形处理能力和游戏特性。它们…...
C语言——I /深入理解指针(二)
一、数组名的理解 int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0];这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,⽽且 是数组⾸元素的地址,我们来做个测试。 #include <stdio.…...
MySQL使用函数和存储过程实现:向数据表快速插入大量测试数据
实现过程 1.创建表 CREATE TABLE user_info (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) DEFAULT NULL,age INT(3) DEFAULT NULL,pwd VARCHAR(20) DEFAULT NULL,phone_number VARCHAR(11) DEFAULT NULL,email VARCHAR(255) DEFAULT NULL,address VARCHAR(255) DEF…...
力扣labuladong——一刷day59
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、力扣549. 二叉树中最长的连续序列二、力扣1325. 删除给定值的叶子节点 前言 像求和、求高度这种基本的二叉树函数很容易写,有时候只要在它们的后…...
接口性能测试 —— Jmeter并发与持续性压测
接口压测的方式: 1、同时并发:设置线程组、执行时间、循环次数,这种方式可以控制接口请求的次数 2、持续压测:设置线程组、循环次数,勾选“永远”,调度器(持续时间),这种…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
python如何将word的doc另存为docx
将 DOCX 文件另存为 DOCX 格式(Python 实现) 在 Python 中,你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是,.doc 是旧的 Word 格式,而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...
数据结构第5章:树和二叉树完全指南(自整理详细图文笔记)
名人说:莫道桑榆晚,为霞尚满天。——刘禹锡(刘梦得,诗豪) 原创笔记:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 上一篇:《数据结构第4章 数组和广义表》…...
