Express 使用中间件

预计阅读时间3 分钟 141 views

概述

Express,作为一个轻量级的Web框架,其核心思想在于路由和中间件机制。简言之,一个Express应用其实就是一系列中间件函数的集合,它们共同协作来处理HTTP请求和响应。

如果当前的中间件函数没有通过调用next()函数来结束其执行并传递控制权,那么请求将被“挂起”,不再继续向下处理。

Express 中间件类型

在Express中,中间件可以分为以下几类:

  • 应用级中间件:这类中间件绑定到整个Express应用上,无论请求的路径是什么,它们都会被执行。
  • 路由级中间件:与特定路由路径相关联的中间件,只有在请求的URL与路由路径匹配时才会被调用。
  • 错误处理中间件:专门用于捕获和处理在请求处理过程中发生的错误。
  • 内置中间件:Express自身提供的一些常用中间件,例如用于解析JSON数据或URL编码数据的中间件。
  • 第三方中间件:由社区开发的中间件,它们为Express应用提供了更多的功能和扩展性。

如何加载中间件?

在Express应用中,你可以通过指定一个可选的挂载路径来加载应用级和路由级中间件。此外,你还可以将多个中间件函数组合在一起,形成一个中间件子堆栈,并在特定的挂载点加载它们。这种灵活的配置方式使得Express应用能够轻松实现各种复杂的请求处理逻辑。

应用级中间件的使用

在 Express 应用中,应用级中间件可以处理所有请求,无论它们的路径或HTTP方法如何。你可以通过 app.use()app.METHOD() 方法将中间件绑定到应用对象的实例。其中 METHOD 是小写的 HTTP 方法名称,如 getpostput 等。

示例:无路径挂载的中间件

以下示例中的中间件函数没有特定的挂载路径,因此它将在每次应用接收到请求时执行。

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

app.use((req, res, next) => {
  console.log('Current Time:', Date.now());
  next();
});

示例:带路径挂载的中间件

这个例子中的中间件函数被挂载在 /user/:id 路径上,它将对所有类型的 HTTP 请求进行处理。

app.use('/user/:id', (req, res, next) => {
  console.log('Request Method:', req.method);
  next();
});

示例:路由及处理函数

以下示例展示了如何为 /user/:id 路径上的 GET 请求定义一个路由处理函数。

app.get('/user/:id', (req, res, next) => {
  res.send('USER');
});

中间件子堆栈

中间件子堆栈允许你为特定路径挂载多个中间件函数。下面的例子中,任何对 /user/:id 路径的 HTTP 请求都会打印出请求的原始 URL 和请求类型。

app.use('/user/:id', (req, res, next) => {
  console.log('Request URL:', req.originalUrl);
  next();
}, (req, res, next) => {
  console.log('Request Method:', req.method);
  next();
});

路由处理程序

你可以为同一路径定义多个路由处理程序。需要注意的是,一旦某个请求被响应,后续的路由处理程序将不会被调用。

app.get('/user/:id', (req, res, next) => {
  console.log('User ID:', req.params.id);
  next();
}, (req, res, next) => {
  res.send('User Info');
});

// 这个路由处理程序实际上不会被调用,因为前一个已经结束了请求-响应周期。
app.get('/user/:id', (req, res, next) => {
  res.send(req.params.id);
});

使用 next('route') 跳过中间件

要跳过当前路由的所有剩余中间件并传递控制权给下一个路由,可以使用 next('route')

app.get('/user/:id', (req, res, next) => {
  if (req.params.id === '0') {
    next('route'); // 跳过当前路由的剩余中间件
  } else {
    next(); // 继续执行当前中间件栈中的下一个中间件
  }
}, (req, res, next) => {
  res.send('regular');
});

// 另一个路由处理程序,当上一个中间件跳过时,这个处理程序会被调用
app.get('/user/:id', (req, res, next) => {
  res.send('special');
});

中间件的数组声明

中间件还可以声明为数组,以提高代码的可重用性。通过这种方式,你可以轻松地将多个中间件逻辑组合在一起,以用于不同的路由。

function logOriginalUrl(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}

function logMethod(req, res, next) {
  console.log('Request Method:', req.method);
  next();
}

const logStuff = [logOriginalUrl, logMethod];

app.get('/user/:id', logStuff, (req, res, next) => {
  res.send('User Info');
});

路由级中间件

路由级中间件与应用级中间件的工作方式相似,但它是绑定到一个特定的路由实例上的。在Express框架中,路由级中间件通过express.Router()创建,并使用router.use()router.METHOD()方法来加载。

示例代码

以下是使用路由级中间件的示例代码,展示了如何在不同的路由上应用中间件。

const express = require('express');
const app = express();
const router = express.Router();

// 通用中间件,打印请求时间和URL
const logRequest = (req, res, next) => {
  console.log('Time:', Date.now(), 'Request URL:', req.originalUrl);
  next();
};

// 特定于/user/:id的中间件,打印请求类型
const logMethod = (req, res, next) => {
  console.log('Request Type:', req.method);
  next();
};

router.use(logRequest); // 应用通用中间件

router.use('/user/:id', logMethod); // 应用特定中间件

// 处理/user/:id路径的GET请求,如果用户ID为0,则跳过当前路由的其余中间件
router.get('/user/:id', (req, res, next) => {
  if (req.params.id === '0') {
    next('route');
  } else {
    // 渲染常规页面
    res.render('regular');
  }
});

// 另一个处理/user/:id路径的GET请求,渲染特殊页面
router.get('/user/:id', (req, res) => {
  console.log(req.params.id);
  res.render('special');
});

// 将router挂载到app上
app.use('/', router);

// 捕获所有未匹配的请求,并返回401状态码
app.use((req, res) => {
  res.sendStatus(401);
});

错误处理中间件

在Node.js的Express框架中,错误处理中间件是一种特殊的中间件,用于处理请求-响应循环中的异常和错误。它通常用于捕获并处理应用中的未捕获错误,确保即使在出现错误的情况下,用户也能得到适当的响应。

错误处理中间件函数的签名与常规中间件不同,它需要四个参数:(err, req, res, next)。这四个参数分别代表:

  1. err:错误对象,包含了错误信息和堆栈跟踪。
  2. req:请求对象,包含了请求的相关信息。
  3. res:响应对象,用于发送响应给客户端。
  4. next:调用下一个中间件的函数(在错误处理中间件中通常不使用)。

定义错误处理中间件

定义错误处理中间件时,确保使用四个参数,并将其放置在所有其他中间件之后,确保它能够捕获到任何未被其他中间件处理的错误。

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

// 常规中间件
app.get('/', (req, res) => {
  res.send('Hello World!');
});

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

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

内置中间件

从Express 4.x版本开始,框架不再依赖于Connect中间件。之前内置在Express中的一些中间件功能现在被分离出来,形成了独立的模块。以下是Express框架提供的内置中间件函数:

  1. express.static:该中间件用于提供静态资源,包括HTML文件、图片、CSS文件等,方便地将这些资源服务给客户端。
  2. express.json:此中间件用于解析传入请求的JSON有效负载。从Express 4.16.0版本开始,该功能被内置到框架中。
  3. express.urlencoded:此中间件用于解析使用URL编码格式的请求负载。同样,从Express 4.16.0版本开始,该功能也被内置到框架中。

注意,虽然这些中间件在Express 4.16.0及以上版本中是内置的,但在早期版本中,它们可能需要单独安装和配置。在实际中,开发者应根据自己使用的Express版本来决定是否需要额外安装这些中间件。

第三方中间件

在Express应用中,第三方中间件可以提供额外的功能和扩展性。以下是如何安装和使用第三方中间件的步骤:

1、安装所需模块:首先,你需要通过npm(Node Package Manager)安装提供所需功能的Node.js模块。以cookie-parser为例,这是一个解析HTTP请求中cookie的中间件。

$ npm install cookie-parser

2、加载中间件到应用:安装完成后,在你的Express应用代码中,需要先引入expresscookie-parser模块,然后通过调用app.use()方法将cookie-parser中间件加载到应用中。

const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');

// 加载cookie解析中间件
app.use(cookieParser());

Express常用的第三方中间件列表

以下是一些常用的第三方中间件的示例,完整的列表请参考 第三方中间件

  • cookie-parser:解析HTTP请求中的cookie。
  • morgan:HTTP请求的日志记录器。
  • body-parser:解析多种格式的请求体,包括JSON、URL编码的表单数据等。
  • cors:提供跨源资源共享(CORS)支持。
  • helmet:帮助保护应用免受某些类型的Web攻击。
  • express-session:为Express添加会话支持。

注意,第三方中间件的可用性和功能可能会随着时间的推移而变化,在选择和使用时,应查阅最新的文档或社区反馈。

分享此文档

Express 使用中间件

或复制链接

本页目录