十一、中间件的使用

news2024/12/27 12:52:09

         Express的应用本质上就是调用各种中间件,中间件指的是业务流程中的中间处理环节,服务器的生命周期一般是 接收 —— 处理 —— 响应;那么中间件就充当处理的角色,它其实就是一个函数,该函数除了能够访问请求对象req和响应对象res,还有next参数(next参数也是一个函数,通过next()可以将控制权交给下一个中间件,调用下一个函数),中间件分自定义中间件、第三方中间、内置中间件和错误中间件。

Express中间件格式:

app.get('/',function(req,res,next){
    // 处理业务逻辑;
    next();   // 调用下一个函数;
})

        中间件函数的形参列表中,必须包含next函数,而路由函数就只有req和res;


自定义中间件

全局生效

1 .在项目入口文件app.js当中定义中间件函数;

const express = require('express');
const app = express();
const getTimes = function getTimes(req,res,next){
    let t_1 = new Date();
    let rs = t_1.getTime();
    console.log("执行结果:",rs);
    next();
}

// 下面代码编写在此

2. 全局注册使用中间件;

app.use(getTimes);

3. 运行测试;

app.get('/',function(req,res){
    res.send('Wecome to express middleware!')
    console.log('已响应!');
})

// 监听端口
app.listen('3000',function(){
    console.log('Server Running ...')
})

        先处理完getTimes中间件的内容将执行结果出来,再将请求http://127.0.0.1:3000的响应结果响应给客户端!

        当然了你也可以简化形式进行代码编写:

const express = require('express');
const app = express();
app.use(function (req,res,next){
    let t_1 = new Date();
    let rs = t_1.getTime();
    console.log('执行结果:',rs);
    next();
})
app.get('/',function(req,res){
    res.send('Wecome to express middleware!')
    console.log('已响应!');
})
app.listen('3000',function(){
    console.log('Server Running ...')
})

        可以通过app.use() 进行连续定义多个中间件,客户端请求到达服务器时,中间会按定义的先后顺序依次进行调用:


局部生效

        全局的生效通过app.use()注册使用,而局部生效则是不使用app.use(),下面来进行定义局部生效的中间件:

const express = require('express');
const app = express();
const getTimes = function getTimes(req,res,next){
    let t_1 = new Date();
    let rs = t_1.getTime();
    console.log("执行结果:",rs);
    next();
}
app.get('/',getTimes,function(req,res){
    res.send('Wecome to express middleware!');
})
app.get('/user',function(req,res){
    res.send('user: admin');
    console.log('响应/user');
})
app.listen('3000',function(){
    consoel.log('Server Running ...');
})

多个局部中间件

const express = reqiure('express');
const app = express();
const getTimes = function getTimes(req,res,next){
    let t_1 = new Date();
    let rs = t_1.getTime();
    console.log("执行结果:",rs);
    next();
}
const getTimesVal = function getTimesVal(req,res,next){
    let t_2 = new Date();
    let rs = t_2.valueOf();
    console.log("执行结果:",rs);
    next();
}
app.get('/',getTimes,getTimesVal,function(req,res){
    res.send('Wecome to express middleware!')
    console.log('已响应!');
})
app.listen('3000',function(){
    console.log('Server Running ...')
})

还可以使用这种以下这种方式:

app.get('/',[getTimes,getTimesVal],function(req,res){
    // 响应内容
})

        客户端请求http://127.0.0.1:3000/ 会先处理中间件的内容再将响应结果响应给客户端 ,而http://127.0.0.1:3000/user


错误中间件

        错误中间件是专门用来捕获整个项目中的异常错误,从而防止项目异常崩溃的问题;错误中间件有四个参数:err、req、res和next,即使不使用next参数也必须声明,否则会被识别为普通的中间件不能处理错误,下面来定义一个错误中间件:

// /routes/index.js - 抛出错误路由
const express = require('express');
const router = express.Router();
router.get('/test',function(req,res,next){
    throw new Error('程序出现异常错误');
})
// 项目入口文件app.js
const express = require('express')
const app = express();
app.get('/',function(req,res){
    res.send('Wecome to express middleware!')
})
app.use(function(err,req,res,next){
    console.log('------------------ERROR-------------------');
    res.send('<h2>&nbsp;&nbsp;) '+ err.message +'</h2>')
    res.status(500).send(err.message);
})
app.listen('3000',function(){
    console.log('Server Running ...')
})

        这里需要注意的是错误中间件只有放在所有中间件、路由函数的后面才可以生效; 


内置中间件

        Express在4.x版本开始,Express的内置中间件作为单独模块存在,Express中内置了这三个比较常用的模块express.static、express.json、express.urlencoded;前面已经讲到了这个express.static,能够快速托管静态资源通过ap.use供外部访问;下面来简单的了解一下:

express.static(root,[options]);

        内置中间件的options可省略,采用默认值;同时也可以设置多个;

app.use(express.static('public'));
app.use(express.static('files'));

        挂载路径前缀:

app.use('/public',express.static('public'));

        具体的操作在express的基本使用中演示过就不在重复;看下一个express.json();express.json 用于解析JSON格式的请求体数据;下面通过Postman来进行测试:

未使用express.json对JSON格式的请求体数据解析:

app.post('/user',function(req,res){
    console.log(req.body);
    res.send('/user')
})

        req.body获取到的请求数据是undefined值,下面来使用进行express.json进行解析

app.use(express.json());

         下面是未使用 express.urlencoded 来获取url-encoded格式 的数据依然是undefined;

        使用 app.use(express.urlencoded) 解析x-www-from-urlencoded 格式;

app.use(express.urlencoded({extended:false}))

 内置中间件express.urlencoded 基于 body-parse 这个第三方的中间件进一步封装出来:

第三方中间件

        在Express4.x的版本当中会经常的使用body-parser第三方中间件来解析请求体数据,下面来安装使用第三方中间件使用:

1. 安装第三方中间件body-parser;

npm install body-parser

2. 导入中间件require和app.use()注册使用;

const express = require('express');
const app = express();
const parser = require('body-parser')
app.use(parser.urlencoded({extended:false}))
app.get('/',function(req,res){
    res.send('Wecome to express middleware!')
})
app.post('/user',function(req,res){
    res.send('/user');
    console.log(req.body);
})
app.listen('3000',function(){
    console.log('Server Running ...')
})


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

        下面使用内置模块querystring,该模块是处理查询字符串,通过这个模块提供的parse()函数,可以将查询字符串解析成对象格式:

// custom.js ——  封装中间件
const qs = require('querystring');

const bodyParser = function(req,res,next){
    let str = '';
    req.on('data',function(chunk){
        str += chunk;
    })
    req.on('end',function(){
        const body = qs.parser('str');
        req.body = body;
    })
    next();
}
module.exports = bodyParser

        引入来使用该中间件并使用Postman进行测试:

// index.js
const express = require('express');
const app = express();
app.get('/',function(req,res){
    res.send('Wecome to express middleware!')
})
app.post('/user',function(req,res){
    res.send('/user');
    console.log(req.body);
})
app.listen('3000',function(){
    console.log('Server Running ...')
})

        以上就是本篇目的全部内容,在后续篇目中来进一步的在综合案例中来去体现,感谢大家的支持!

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

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

相关文章

TC275——02板卡简单介绍

前部 核心&#xff1a;英飞凌 32位 AURIXTC275 TriCore核 开发工具&#xff1a; AURIX™Development Studio、FreeEntryToolchain CPU&#xff1a; 最大频率&#xff1a;200M外部晶振&#xff1a;20MFPU&#xff1a;支持封装&#xff1a;LQFP176-22 FLASH&#xff1a;4M D…

高并发系统设计 -- 性能测试

响应时间&#xff1a;是客户发出请求到得到响应的整个过程的时间。 网络传输时间&#xff1a;N1N2N3N4应用服务器处理时间&#xff1a;A1A3数据库服务器处理时间&#xff1a;A2响应时间&#xff1a;N1A1N2A2N3A3N4 负载&#xff1a;模拟业务操作对服务器造成压力的过程&#x…

shell-函数与数组

1.编写函数&#xff0c;实现打印绿色OK和红色FAILED 判断是否有参数&#xff0c;存在为Ok&#xff0c;不存在为FAILED [rootcotenos day06]# vim colour.sh #!/bin/bash test(){if [ -z $1 ];thenecho -e "\033[31m FAILED \033[0m"elseecho -e "\033[32m …

git tutorial

最近老板要搞retreat 需要做一个分享&#xff0c;正好把分享的内容作为博客记录一下。 说起git&#xff0c;那就不得不提GitHub。 GitHub 最开始是作为一个面向开源以及私有项目的管理平台。它可以存储代码&#xff0c;文档&#xff0c;数据等等。目前最常用将其作为一个代码…

中点分割裁剪算法介绍 (简单易懂)

目录 一、算法介绍 二、算法描述 一、算法介绍 裁剪效果图&#xff1a; 中点分割裁剪算法的思想类似于二分思想&#xff0c;不断地在中点处将线段一分为二&#xff0c;对每段线段重复Cohen-Sutherland裁剪算法的线段可见性测试方法&#xff0c;直至找到每段线段与窗口边界线的…

STM32MP157驱动开发——Linux块设备驱动

STM32MP157驱动开发——Linux块设备驱动一、简介二、驱动开发1.使用请求队列的方式2.测试①3.不使用请求队列的方式4.测试②参考文章&#xff1a;【正点原子】I.MX6U嵌入式Linux驱动开发——Linux 块设备驱动 一、简介 之前学习的都是关于字符设备的驱动&#xff0c;包括 plat…

Node.js下载安装与基础操作

&#x1f973;博 主&#xff1a;初映CY的前说 &#x1f31e;个人信条&#xff1a;想要变成得到&#xff0c;中间还有做到&#xff01; &#x1f918;本文核心&#xff1a;Node.js的下载安装操作 node.js下载安装 node.js中文网下载链接http://nodejs.cn/download/ 1.浏…

模型性能分析:ROC 分析和 AUC

本文[1]将介绍模型性能分析的两个方法&#xff1a;ROC & AUC。 ROC 分析和曲线下面积 (AUC) 是数据科学中广泛使用的工具&#xff0c;借鉴了信号处理&#xff0c;用于评估不同参数化下模型的质量&#xff0c;或比较两个或多个模型的性能。 传统的性能指标&#xff0c;如准确…

什么是进程、线程,什么是并发、并行及线程的创建和线程的基本使用

一、什么是程序、进程、线程 1、什么是程序 程序可以理解为是我们执行的一段代码&#xff0c;是一种静态的概念 2、什么是进程 进程是指运行中的程序&#xff0c;是一个动态的概念。进程有它自身的产生、存在和消亡的过程&#xff08;进程产生就会占用内存空间&#xff0c;反…

【WSL】[04]从C盘解放出来WSL的linux镜像

前言&#xff1a; C盘的硬盘资源有限&#xff0c;虚拟机的需求无限&#xff0c;所以&#xff0c;要把无限的硬盘需求搞到其他盘去才行啊 方案1&#xff1a;利用工具&#xff1a;move-wsl 1 管理员运行PowerShell,创建WSL的工作目录 移动前&#xff0c;C盘的空间大小&#xf…

vue-element-表格 Excel 【导出】功能

表格Excel导出功能 1. 将点击导出按钮添加点击事件click“handleDownload” 并在method中创建方法 <el-button type"danger" size"small" click"handleDownload">excel导出</el-button>复制下面的方法 or 去vue-element-admin中的s…

分享62个PHP源码,总有一款适合您

链接&#xff1a;https://pan.baidu.com/s/17mzEPqFhZp0UEvznSviiEA?pwdnjin 提取码&#xff1a;njin PHP源码 分享62个PHP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c;大家下载后…

【C语言简明教程】探究整型数据在内存中的存储

概述 我们知道一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同的类型而决定的。那么整型数据在所开辟内存中到底是如何存储的&#xff1f; 目录 概述 原码、反码、补码 什么是原码、反码和补码&#xff1f; 为什么使用补码存储&#xff1f; 大小端存储 - 数据…

Hadoop高手之路6-ZooKeeper

文章目录Hadoop高手之路6-Zookeeper分布式协调服务一、Zookeeper简介二、Zookeeper的特性1. 一致性C2. 可靠性3. 顺序性4. 原子性A5. 实时性三、Zookeeper分布式集群的部署1. 下载安装包2. 上传3. 解压4. 配置环境变量5. 配置Zookeeper1) 复制一个配置模板文件2) 修改配置文件3…

C语言排序算法

冒泡排序&#xff08;英语&#xff1a;Bubble Sort&#xff09;是一种简单的排序算法。它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果他们的顺序&#xff08;如从大到小、首字母从A到Z&#xff09;错误就把他们交换过来。 过程演示&#xff1a; #i…

shell第二天练习

题目 1、编写一个 Shell脚本&#xff0c;程序执行时从键盘读入一个目录名&#xff0c;如果用户输入的目录不存在&#xff0c;则提示file does not exist&#xff1b;如果用户输入的不是目录则提示用户必须输入目录名&#xff1b;如果用户输入的是目录则显示这个目录下所有文件…

django笔记《模型和数据库一》

文章目录1 前言2 创建一个demo项目2.1 修改配置文件3 模型3.1 主键3.2 django 内置字段类型3.3 自定义字段类型3.4 django字段选项3.5 字段备注名3.5 META3.6 关联关系3.6.1 多对一关系3.6.2 多对多关系3.6.3 一对一关系3.7 字段命名限制3.8 模型属性&#xff1a;Model.objects…

基于springboot+Vue前后端分离的招聘管理系统(程序+数据库+文档)

大家好✌&#xff01;我是CZ淡陌。一名专注以理论为基础实战为主的技术博主&#xff0c;将再这里为大家分享优质的实战项目&#xff0c;本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路…

A Survey on Deep Learning Techniques for Stereo-based Depth Estimation论文阅读

1. 摘要 估计RGB图片的深度是一个长期存在的病态问题&#xff0c;计算机视觉、图形学、机器学习社区已经探索了数十年。立体匹配是最广泛见诸文献的技术之一&#xff0c;因为它与人类的双目系统有强关联。传统上&#xff0c;利用多张图片的人工特征匹配来处理基于立体的深度估…

nginx 实现图片防盗链功能

在搜索浏览网页的时候&#xff0c;发现一篇文章是从我的个人网站转载的&#xff0c;但是没有注明出处&#xff0c;文章中的图片也没有本地化处理&#xff0c;还是从我的服务器请求&#xff0c;这就无形中增加了我的服务器的开销&#xff0c;于是有了设置防盗链功能这一想法。 …