
在 Node.js 的 Web 服务器开发领域,Express 框架是一个强大且受欢迎的工具。而中间件则是 Express 框架的核心特性之一,它就像是一个个“关卡”,可以对请求和响应进行处理、转换和拦截,极大地增强了应用的灵活性和可扩展性。本文将深入探讨 Express 中间件的使用。
Express 中间件是一个函数,它可以访问请求对象(req)、响应对象(res)以及应用程序请求 - 响应循环中的下一个中间件函数(通常命名为 next)。中间件函数可以执行以下任务:
如果当前中间件函数没有结束请求 - 响应循环,它必须调用 next() 方法将控制权传递给下一个中间件函数。否则,请求将被挂起。
应用级中间件绑定到 express 实例,使用 app.use() 或 app.METHOD() 方法。以下是一个简单的示例:
const express = require('express');const app = express();// 应用级中间件app.use((req, res, next) => {console.log('这是一个应用级中间件');next();});app.get('/', (req, res) => {res.send('Hello, World!');});const port = 3000;app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);});
在上述代码中,我们定义了一个应用级中间件,它会在每个请求到达时打印一条日志信息,然后调用 next() 方法将控制权传递给下一个中间件或路由处理函数。
路由级中间件的工作方式与应用级中间件相同,只是它绑定到 express.Router() 实例。示例如下:
const express = require('express');const app = express();const router = express.Router();// 路由级中间件router.use((req, res, next) => {console.log('这是一个路由级中间件');next();});router.get('/', (req, res) => {res.send('这是路由的根路径');});app.use('/route', router);const port = 3000;app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);});
这里我们创建了一个路由实例 router,并为其添加了一个中间件。当访问 /route 路径时,会先执行路由级中间件,然后再执行对应的路由处理函数。
错误处理中间件有四个参数 (err, req, res, next),用于处理应用程序中出现的错误。示例如下:
const express = require('express');const app = express();app.get('/', (req, res, next) => {try {throw new Error('发生错误');} catch (err) {next(err);}});// 错误处理中间件app.use((err, req, res, next) => {console.error(err.stack);res.status(500).send('服务器内部错误');});const port = 3000;app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);});
当路由处理函数中抛出错误时,会调用 next(err) 将错误传递给错误处理中间件,错误处理中间件会捕获错误并返回相应的错误信息。
Express 提供了一些内置中间件,如 express.static 用于提供静态文件服务。示例如下:
const express = require('express');const app = express();// 内置中间件,提供静态文件服务app.use(express.static('public'));const port = 3000;app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);});
在上述代码中,我们使用 express.static 中间件将 public 目录下的文件作为静态文件提供给客户端访问。
第三方中间件是由社区开发的,可以通过 npm 安装和使用。例如,body-parser 用于解析请求体。示例如下:
const express = require('express');const bodyParser = require('body-parser');const app = express();// 第三方中间件,解析请求体app.use(bodyParser.json());app.post('/', (req, res) => {console.log(req.body);res.send('收到请求体');});const port = 3000;app.listen(port, () => {console.log(`服务器运行在 http://localhost:${port}`);});
在这个示例中,我们使用 body-parser 中间件来解析 JSON 格式的请求体,以便在路由处理函数中可以方便地访问请求体数据。
| 中间件类型 | 描述 | 示例代码 |
|---|---|---|
| 应用级中间件 | 绑定到 express 实例,处理所有请求 |
app.use((req, res, next) => { console.log('应用级中间件'); next(); }); |
| 路由级中间件 | 绑定到 express.Router() 实例,处理特定路由的请求 |
router.use((req, res, next) => { console.log('路由级中间件'); next(); }); |
| 错误处理中间件 | 处理应用程序中出现的错误,有四个参数 | app.use((err, req, res, next) => { console.error(err.stack); res.status(500).send('服务器内部错误'); }); |
| 内置中间件 | Express 提供的中间件,如 express.static |
app.use(express.static('public')); |
| 第三方中间件 | 由社区开发的中间件,通过 npm 安装使用 |
const bodyParser = require('body-parser'); app.use(bodyParser.json()); |
Express 中间件是构建灵活、可扩展 Web 应用的关键。通过合理使用不同类型的中间件,我们可以对请求和响应进行各种处理,提高代码的复用性和可维护性。无论是简单的日志记录,还是复杂的错误处理,中间件都能发挥重要作用。希望本文能帮助你更好地理解和使用 Express 中间件。