【express-generator】05-路由中间件和错误处理(第一阶段收尾)

一、前言

上篇文章我们介绍了express-generator的请求体解析,重点讲了常用的请求体数据格式(JSON/URL 编码的表单数据)以及一个FILE文件上传,同时搭配代码示范进行辅助理解。

二、本篇重点

我们继续第一阶段的知识,本篇把最后两个知识点(路由中间件和错误请求)讲完,顺利完成第一阶段的初步认识和学习。

三、知识点:路由中间件

1、路由中间件是什么?

路由中间件是 Express 中的一个强大功能,它允许你在处理请求之前和之后执行自定义逻辑。中间件可以用于各种任务,如日志记录、身份验证、数据验证等。 

 路由中间件可以被理解为一个函数,它接收三个参数:req(请求对象)、res(响应对象)和 next(函数)。这个函数可以对这三个参数进行操作,并且通过这些操作来影响 Express 服务器的行为。以下是路由中间件的一些关键点:

  1. 接收参数

    • req(请求对象):包含了请求的所有信息,如请求方法、URL、请求头、请求体等。中间件可以读取和修改 req 对象的属性。
    • res(响应对象):用于向客户端发送响应。中间件可以发送响应、设置响应头、设置响应状态码等。
    • next(函数):调用 next() 可以将控制权传递给下一个中间件或路由处理函数。如果不调用 next(),请求处理流程将停止。
  2. 操作和影响

    • 读取和修改请求信息:中间件可以读取请求中的数据,如解析请求体、获取请求头信息等。也可以修改请求对象,如添加自定义属性、修改请求参数等。
    • 发送响应:中间件可以直接向客户端发送响应,结束请求处理流程。例如,可以发送错误响应、重定向响应等。
    • 执行自定义逻辑:中间件可以执行各种自定义逻辑,如身份验证、日志记录、数据验证、缓存处理等。
    • 错误处理:中间件可以捕获和处理错误,将错误传递给错误处理中间件,或者直接发送错误响应。

 中间件的执行顺序

  • 顺序执行:中间件按照它们在 app.use() 中被调用的顺序执行。每个中间件都有机会处理请求,并决定是否将控制权传递给下一个中间件。
  • 调用 next():中间件通过调用 next() 函数来将控制权传递给下一个中间件。如果中间件不调用 next(),请求处理流程将停止,不会执行后续的中间件或路由处理函数。

2、express-generator创建express应用程序,默认使用的路由中间件

 首先让我们看看使用express-generator创建一个express应用程序时,app.js默认使用的路由中间件有哪些

知识点相关介绍: 

1. logger('dev')

  • 作用:使用 morgan 日志记录器中间件,记录 HTTP 请求的详细信息。
  • 配置'dev' 是 morgan 的预定义格式之一,它会在开发环境中提供简洁的彩色日志输出,包括请求方法、URL、响应状态码和响应时间等。
  • 使用场景:用于开发环境中的日志记录,帮助开发者监控和调试应用程序。

2. express.json()

  • 作用:解析 JSON 格式的请求体。
  • 使用场景:用于处理客户端发送的 JSON 数据,例如 API 请求中的 JSON 数据。

3. express.urlencoded({ extended: false })

  • 作用:解析 URL 编码的请求体。
  • 配置{ extended: false } 表示使用内置的查询字符串解析器,它只能解析简单的键值对,不支持嵌套对象或数组。
  • 使用场景:用于处理 HTML 表单提交的数据,这些数据通常以 application/x-www-form-urlencoded 格式发送。

4. cookieParser()

  • 作用:解析客户端发送的 Cookie。
  • 使用场景:用于处理客户端发送的 Cookie,以便在服务器端进行身份验证或其他需要 Cookie 的操作。

5. express.static(path.join(__dirname, 'public'))

  • 作用:提供静态文件服务。
  • 配置path.join(__dirname, 'public') 指定了静态文件的目录,通常是项目的 public 目录。
  • 使用场景:用于提供网站的静态资源,如图片、CSS、JavaScript 文件等,使得客户端可以直接访问这些文件。

 3、动手写一个简单的路由中间件

const express = require('express');
const app = express();// 定义一个日志记录中间件
function logRequest(req, res, next) {const { method, url } = req;console.log(`Received ${method} request for ${url}`);next(); // 调用下一个中间件 
}// 使用中间件
app.use(express.json())  //解析请求体数据
app.use(logRequest);     //日志记录中间件
app.get('/', (req, res) => {res.send('Hello, World!');
});
app.post('/user', (req, res) => {console.log("接收的请求体参数>>>",req.body);res.send(req.body);});app.listen(3009, () => {console.log('Server is running on port 3009');
});

 启动服务器,打开apipost工具进行路由测试

 在这个示例中,logRequest 中间件会在每个请求到达时记录请求方法和 URL。

四、知识点:错误处理

错误处理是任何 Web 应用程序的重要组成部分。在 Express 中,错误处理中间件用于捕获和处理在请求处理过程中发生的错误。

常用知识点

  • 错误处理中间件:必须有四个参数:errreqres 和 next
  • 抛出错误:在中间件或路由处理函数中使用 next(err) 来传递错误。
  • 自定义错误对象:可以创建自定义错误对象以提供更详细的错误信息。

 1、常见的错误类型

  1. 语法错误:由于代码编写错误导致的错误,如拼写错误、语法不正确等。
  2. 运行时错误:在代码执行过程中发生的错误,如访问未定义的变量、调用不存在的方法等。
  3. HTTP 错误:与 HTTP 请求和响应相关的错误,如 404(未找到)、500(服务器内部错误)等。
  4. 输入验证错误:由于用户输入不符合预期格式或规则导致的错误。
  5. 数据库错误:与数据库操作相关的错误,如查询失败、连接错误等。

2、错误处理中间件

错误处理中间件是 Express 中用于处理错误的特殊中间件。它有四个参数:errreqresnext。当在中间件或路由处理函数中调用 next(err) 时,控制权会传递给错误处理中间件。

 一个简单的代码示范

const express = require('express');
const app = express();// 模拟一个路由处理函数,可能会抛出错误
app.get('/error', (req, res, next) => {const error = new Error('Something went wrong!');error.status = 500; // 设置 HTTP 状态码next(error); // 将错误传递给错误处理中间件
});// 错误处理中间件
app.use((err, req, res, next) => {console.error(err.stack); // 记录错误堆栈res.status(err.status || 500).json({error: {message: err.message}});
});app.listen(3009, () => {console.log('Server is running on port 3009');
});

 启动服务器,在apipost工具中进行测试。

点击发送,得到结果

3、自定义错误对象

自定义错误对象可以帮助我们更清晰地表示特定类型的错误,并提供额外的上下文信息。

以下是一个自定义错误对象的简单代码示范。

const express = require('express');
const app = express();// 自定义错误类
class CustomError extends Error {constructor(message, status) {super(message);this.status = status;this.name = 'CustomError';}
}// 模拟路由 1:抛出自定义错误
app.get('/custom-error', (req, res, next) => {const error = new CustomError('Custom error occurred', 400);next(error);
});// 模拟路由 2:抛出普通错误
app.get('/error', (req, res, next) => {const error = new Error('Something went wrong!');error.status = 500;next(error);
});// 错误处理中间件
app.use((err, req, res, next) => {console.error(err.stack);res.status(err.status || 500).json({error: {message: err.message,name: err.name}});
});app.listen(3009, () => {console.log('Server is running on port 3009');
});

启动服务,打开apipost攻击进行测试

 


五、总结

至此,我们初步完成第一阶段的所有知识学习以及练习。多动手实践,举一反三,希望文章的案例会对大家有所帮助。

接下来的文章,我们接着第二阶段的知识学习以及代码案例练习。第二阶段的大纲如下:

第二阶段:进阶与应用

  1. RESTful API 设计

    • 学习如何设计符合 REST 原则的 API,包括资源的表示和 HTTP 方法的使用。

  2. 路由分组

    • 学习如何使用路由分组来组织相关的路由,提高代码的可维护性。

  3. 路由重定向

    • 学习如何使用 res.redirect() 和 res.location() 来实现路由重定向。

  4. CRUD 操作

    • 练习实现完整的 CRUD 操作的路由,包括与数据库的交互。 


如果你喜欢这篇文章,请点赞收藏。

关注我,获取前端更多使用知识。

最近业务需求多,会比较忙,但我也会抽出时间进行更新文章,敬请期待。

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

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

相关文章

Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开

element文档链接: https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注:Vue3在样式中修改箭头图标无效,可能我设置不对,欢迎各位来交流指导 转变思路:隐藏箭头&…

【Javascript Day1】javascript基础

javascript编程规则 弹窗&#xff08;举例&#xff09; alert("内容")&#xff0c;直接写在控制区生效 三种写法 1、行内js语法 &#xff1a;需要注意引号的问题 <input type"button" value"提示窗" οnclick alert("消息") &…

GitLab创建用户,设置访问SSH Key

继上一篇 Linux Red Hat 7.9 Server安装GitLab-CSDN博客 安装好gitlab&#xff0c;启用管理员root账号后&#xff0c;开始创建用户账户 1、创建用户账户 进入管理后台页面 点击 New User 输入用户名、邮箱等必填信息和登录密码 密码最小的8位&#xff0c;不然会不通过 拉到…

QT鼠标、键盘事件

一、鼠标 鼠标点击 mousePressEvent 鼠标释放 mouseReleaseEvent 鼠标移动 mouseMoveEvent 鼠标双击 mouseDoubleClickEvent 鼠标滚轮 QWheelEvent 二、键盘 键盘按下 keyPressEvent 键盘松开keyReleaseEvent 一、鼠标 #include <QMouseEvent> 鼠标点击 mouse…

数据库环境安装(day1)

网址&#xff1a;MySQL 下载&#xff08;环境准备&#xff09;&#xff1a; &#xff08;2-5点击此处&#xff0c;然后选择合适的版本&#xff09; 1.linux在线YUM仓库 下载/安装: wget https://repo.mysql.com//mysql84-community-release-el9-1.noarch.rpm rpm -i https://r…

Qt 5.14.2 学习记录 —— 칠 QWidget 常用控件(2)

文章目录 1、Window Frame2、windowTitle3、windowIcon4、qrc机制5、windowOpacity 1、Window Frame 在运行Qt程序后&#xff0c;除了用户做的界面&#xff0c;最上面还有一个框&#xff0c;这就是window frame框。对于界面的元素&#xff0c;它们的原点是Qt界面的左上角或win…

以太网协议在汽车应用中的动与静

为了让网络中的设备能够随时或随地接入网络或离开网络&#xff0c;做到&#xff1a;接入时无需多余的配置就能和其他设备互相通信&#xff1b;离开时又不会导致设备或网络崩溃。以太网从物理层到协议层展现出多方面的灵活性&#xff0c;&#xff0c;使其成为连接各种设备和系统…

牛客网刷题 ——C语言初阶(6指针)——BC105 矩阵相等判定

1. 题目描述&#xff1a;BC105 矩阵相等判定 牛客网OJ题链接 描述&#xff1a; KiKi得到了两个n行m列的矩阵&#xff0c;他想知道两个矩阵是否相等&#xff0c;请你回答他。(当两个矩阵对应数组元素都相等时两个矩阵相等)。 示例1 输入&#xff1a; 2 2 1 2 3 4 1 2 3 4 输出…

外观设计模式学习

1.介绍 外观模式&#xff08;Facade Pattern&#xff09; 是一种结构型设计模式&#xff0c;通过提供一个统一的接口&#xff0c;用于访问子系统中的一组接口&#xff0c;从而简化客户端与复杂系统之间的交互。它隐藏了系统的复杂性&#xff0c;使得客户端只需与一个简单的接口…

基于单片机的数字气压计设计

摘要:在嵌入式技术快速发展过程中&#xff0c;智能测量仪器被广泛应用于工业生产以及人们日常生活领域。数字气压计在实际应用中&#xff0c;利用气压传感器检测环境中的压力大小&#xff0c;便于实现对设备进行智能化的控制操作。数字气压计在气象监测、矿产开采、科学实验等环…

嵌入式软件C语言面试常见问题及答案解析(三)

嵌入式软件C语言面试常见问题及答案解析(三) 上一篇已经足够长了,再长也就有点不礼貌了,所以在这儿继续来总结分享那个面试中遇到的题目,文中的问题和提供的答案或者代码均代表个人的理解,如有不合理或者错误的地方,欢迎大家批评指正。 本文中题目列表 1. 编码实现子串定…

HTML5实现好看的中秋节网页源码

HTML5实现好看的中秋节网页源码 前言一、设计来源1.1 网站首页界面1.2 登录注册界面1.3 节日由来界面1.4 节日习俗界面1.5 节日文化界面1.6 节日美食界面1.7 节日故事界面1.8 节日民谣界面1.9 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看…

ROS通信编程——服务通信

前言 学完了话题通信其实操作流程基本都已经很熟悉了&#xff0c;因此服务通讯的学习就会流畅许多。 服务通信也是ROS中一种极其常用的通信模式&#xff0c;服务通信是基于请求响应模式的&#xff0c;是一种应答机制。也即: 一个节点A向另一个节点B发送请求&#xff0c;B接收…

零基础微信小程序开发——全局配置之tabBar(保姆级教程+超详细)

&#x1f3a5; 作者简介&#xff1a; CSDN\阿里云\腾讯云\华为云开发社区优质创作者&#xff0c;专注分享大数据、Python、数据库、人工智能等领域的优质内容 &#x1f338;个人主页&#xff1a; 长风清留杨的博客 &#x1f343;形式准则&#xff1a; 无论成就大小&#xff0c;…

2024年12月HarmonyOS应用开发者高级认证全新题库

注意事项&#xff1a;切记在考试之外的设备上打开题库进行搜索&#xff0c;防止切屏三次考试自动结束&#xff0c;题目是乱序&#xff0c;每次考试&#xff0c;选项的顺序都不同&#xff0c;作者已于2024年12月15日又更新了一波题库&#xff0c;题库正确率99%&#xff01; 新版…

【网络协议】IPv4 地址分配 - 第二部分

前言 在第 1 部分中&#xff0c;我们学习了 IPv4 地址的分配方式&#xff0c;了解了各种类型的 IPv4 地址&#xff0c;并进行了基础的子网划分&#xff08;Subnetting&#xff09;。在第 2 部分中&#xff0c;我们将继续学习子网划分&#xff0c;并引入一些新的概念。 【网络…

浙江安吉成新的分布式光伏发电项目应用

摘 要&#xff1a;分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上&#xff0c;利用太阳能进行发电的一种可再生能源利用方式&#xff0c;与传统的大型集中式光伏电站相比&#xff0c;分布式光伏发电具有更灵活的布局、更低的建设成本和更高…

7z 安装与使用指南

文章目录 1. 安装 7z1.1 在 Linux 上安装 7z对于 Debian/Ubuntu 系统&#xff1a;对于 CentOS/RHEL 系统&#xff1a;对于 Fedora 系统&#xff1a;对于 Arch Linux 系统&#xff1a; 1.2 在 Windows 上安装 7z 2. 使用 7z 进行压缩和解压2.1 压缩文件示例&#xff1a;压缩一个…

scanf:数据之舟的摆渡人,静卧输入港湾的诗意守候

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一节我们主要来学习scanf的基本用法&#xff0c;了解scanf返回值&#xff0c;懂得scanf占位符和赋值…

【ROS2】Arduino系列之电机驱动实现

内容学自&#xff1a;赵虚左老师。学后总结&#xff01; 实现机器人移动的一种策略是&#xff1a;控制系统会先发布预期的车辆速度信息&#xff0c;然后驱动系统订阅到该信息&#xff0c;不断调整电机转速直至达到预期速度&#xff0c;调速过程中还需要时时获取实际速度并反馈…