首页 > 其他分享 >第5章 Express中间件的深入理解(一)

第5章 Express中间件的深入理解(一)

时间:2024-07-18 23:27:39浏览次数:9  
标签:req 自定义 res app Express 中间件 next 深入

中间件是 Express 的核心概念之一,它们可以拦截请求和响应,以便在请求到达路由处理函数之前或在响应发送给客户端之前执行某些操作。在本章中,我们将深入探讨中间件的类型、用法以及如何编写自定义中间件。

1 中间件概述

中间件是具有访问请求对象 (req)、响应对象 (res) 和下一个中间件函数 (next) 的函数。中间件函数可以执行以下任务:

  • 执行任何代码。
  • 修改请求和响应对象。
  • 结束请求-响应循环。
  • 调用堆栈中的下一个中间件函数。
1.1 应用级中间件

应用级中间件绑定到 app 实例,作用于应用的全局或特定路由。

示例:

const express = require('express');
const app = express();

// 应用级中间件,所有请求都会执行
app.use((req, res, next) => {
    console.log('Time:', Date.now());
    next(); // 调用下一个中间件
});

// 应用级中间件,特定路径请求才会执行
app.use('/user/:id', (req, res, next) => {
    console.log('Request Type:', req.method);
    next();
});

// 路由
app.get('/user/:id', (req, res) => {
    res.send(`User ID: ${req.params.id}`);
});

// 启动服务器
const port = 3000;
app.listen(port, () => {
    console.log(`Server is running on http://localhost:${port}`);
});

在这里插入图片描述

代码详解:

  • app.use((req, res, next) => {}):定义应用级中间件。
  • next():调用下一个中间件或路由处理函数。
1.2 路由级中间件

路由级中间件绑定到 express.Router 实例,作用于特定路由。

示例:

const router = express.Router();

// 路由级中间件
router.use((req, res, next) => {
    console.log('Router-level middleware');
    next();
});

// 路由
router.get('/profile', (req, res) => {
    res.send('User profile page');
});

router.get('/settings', (req, res) => {
    res.send('User settings page');
});

// 将路由器挂载到应用中
app.use('/user', router);

代码详解:

  • router.use((req, res, next) => {}):定义路由级中间件。
  • app.use('/user', router):将路由器挂载到应用中。
1.3 错误处理中间件

错误处理中间件是带有四个参数的函数,用于处理传递过来的错误。

示例:

// 普通中间件
app.get('/error', (req, res, next) => {
    const err = new Error('Something went wrong');
    next(err); // 将错误传递给错误处理中间件
});

// 错误处理中间件
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Internal Server Error');
});

代码详解:

  • 错误处理中间件:带有四个参数 errreqresnext
1.4 内置中间件

Express 提供了一些内置的中间件,如 express.json()express.urlencoded()

示例:

// 解析 JSON 请求体
app.use(express.json());

// 解析 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));

代码详解:

  • express.json():解析 JSON 请求体。
  • express.urlencoded({ extended: true }):解析 URL 编码的请求体。
1.5 第三方中间件

可以使用许多第三方中间件来扩展 Express 的功能,如 morgancors 等。

示例:

const morgan = require('morgan');

// 使用 morgan 中间件记录 HTTP 请求日志
app.use(morgan('combined'));

代码详解:

  • morgan('combined'):使用 morgan 记录 HTTP 请求日志。
2 编写自定义中间件

自定义中间件是你自己编写的用于特定需求的中间件。自定义中间件可以在应用级或路由级使用。

2.1 简单的自定义中间件

示例:

// 自定义中间件,记录请求方法和路径
app.use((req, res, next) => {
    console.log(`Request Method: ${req.method}, Request Path: ${req.path}`);
    next(); // 调用下一个中间件或路由处理函数
});

代码详解:

  • console.log():记录请求方法和路径。
2.2 带参数的自定义中间件

可以编写带参数的自定义中间件,以便灵活配置。

示例:

// 带参数的自定义中间件工厂函数
function requestLogger(options) {
    return (req, res, next) => {
        if (options.logMethod) {
            console.log(`Request Method: ${req.method}`);
        }
        if (options.logPath) {
            console.log(`Request Path: ${req.path}`);
        }
        next();
    };
}

// 使用带参数的自定义中间件
app.use(requestLogger({ logMethod: true, logPath: true }));

代码详解:

  • requestLogger(options):自定义中间件工厂函数,根据传入的选项参数配置中间件行为。
2.3 异步自定义中间件

自定义中间件可以是异步的,用于处理异步操作。

示例:

// 异步自定义中间件,模拟数据库查询
app.use(async (req, res, next) => {
    try {
        const data = await fetchDataFromDatabase();
        req.data = data; // 将数据存储在请求对象中
        next(); // 调用下一个中间件或路由处理函数
    } catch (error) {
        next(error); // 将错误传递给错误处理中间件
    }
});

async function fetchDataFromDatabase() {
    // 模拟异步数据库查询
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve({ message: 'Data fetched from database' });
        }, 1000);
    });
}

代码详解:

  • async (req, res, next):异步自定义中间件。
  • await fetchDataFromDatabase():等待异步操作完成。
  • next(error):将错误传递给错误处理中间件。

标签:req,自定义,res,app,Express,中间件,next,深入
From: https://blog.csdn.net/imdeity/article/details/140274466

相关文章

  • 深入理解 Vue 3 组件通信
    在Vue3中,组件通信是一个关键的概念,它允许我们在组件之间传递数据和事件。本文将介绍几种常见的Vue3组件通信方法,包括props、emits、provide和inject、事件总线以及Vuex状态管理。1.使用props和emits进行父子组件通信props传递数据props是父组件向子组件传递......
  • 深入探索Java:揭秘流式解析JSON的神秘面纱
    哈喽,大家好,我是木头左!前言在当今数据驱动的时代,处理JSON数据已成为日常开发中不可或缺的一部分。对于Java开发者来说,能够高效、灵活地解析JSON数据是至关重要的技能。本篇文章将带你深入了解如何使用Java进行JSON解析,特别是通过JsonReader进行流式解析,以及如何优雅地处理嵌套......
  • [GYCTF2020]Ez_Express 1
    原型链污染,信息收集,命令执行,代码审计这个题我在做之前学了p神的教程https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html打开后可以发现是一个登录界面,之后我们先进行信息收集找到了www.zip这个文件,然后得到了源码index.jsvarexpress=req......
  • 深入解析微服务架构之Spring Cloud
    目录微服务架构简介什么是微服务微服务的优势微服务的挑战SpringCloud概述SpringCloud简介SpringCloud的主要特性SpringCloud的模块划分SpringCloud核心组件详解SpringCloudNetflixSpringCloudConfigSpringCloudGatewaySpringCloudSleuthSpringCloudBu......
  • devexpress dxNavBar 用法
    unitUnit2;interfaceusesWinapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,cxGraphics,cxControls,cxLookAndFeels,cxLookAndFeelPainters,dxNavBarGroupItems,dxNavBarCollns,......
  • 深入解析`Arrays.asList`的用法与潜在陷阱
    引言在Java编程中,Arrays.asList是一个常用的工具方法,用于将数组转换为List。尽管其使用简单,但在实际应用中存在一些潜在的陷阱和误解。本文将深入探讨Arrays.asList的用法、其底层实现机制以及常见的陷阱,辅之以数据和实际案例分析。Arrays.asList的基本用法Arrays.asLis......
  • 深入浅出Spring Web MVC:从零开始构建你的第一个Web应用
    深入浅出SpringWebMVC:从零开始构建你的第一个Web应用大家好,今天我们来聊聊SpringWebMVC,这是一个非常强大的框架,用于构建JavaWeb应用。我们将从零开始,逐步构建一个简单的Web应用,帮助大家理解SpringWebMVC的核心概念和使用方法。什么是SpringWebMVC?SpringWebMVC是Spri......
  • 深入探讨:使用 Spring AOP 实现 Lock4j 的声明式和编程式分布式锁
    深入探讨:使用SpringAOP实现Lock4j的声明式和编程式分布式锁在现代分布式系统中,分布式锁是一个非常重要的概念。它可以帮助我们在多个节点之间协调资源访问,防止数据不一致和竞争条件。今天,我们将深入探讨如何使用Lock4j和SpringAOP来实现声明式和编程式的分布式锁。什......
  • 深入解析 Spring Boot 项目中的 Maven 依赖冲突及其解决方案
    深入解析SpringBoot项目中的Maven依赖冲突及其解决方案在使用SpringBoot开发项目时,Maven作为构建工具为我们提供了极大的便利。然而,随着项目规模的扩大和依赖项的增多,依赖冲突问题也随之而来。本文将深入探讨SpringBoot项目中Maven依赖冲突的原因、检测方法以及解......
  • 深入探讨 Spring 6 的面向切面编程(AOP)
    深入探讨Spring6的面向切面编程(AOP)大家好,今天我们来聊聊Spring6中的面向切面编程(AOP)。AOP是Spring框架中一个非常强大的特性,它可以帮助我们在不改变原有代码的情况下,添加一些通用的功能,比如日志记录、事务管理、安全检查等。什么是AOP?AOP,全称Aspect-OrientedProgra......