摘要:在本教程中,您将了解 Express 中间件并理解其工作原理。
Express 中间件简介
在 Express 中,中间件是一个可以访问以下对象的函数
- 请求对象 (
req
)。 - 响应对象 (
res
)。 - 下一个中间件函数 (
next
)。
从技术上讲,Express 应用程序是一系列中间件函数调用的集合
以下定义了一个中间件函数
function fn(req, res, next) {
// ...
}
Code language: JavaScript (javascript)
通常,您使用中间件来执行以下任务
- 更改请求和响应对象。
- 终止请求-响应循环。
- 向请求/响应循环添加自定义逻辑,例如验证、身份验证和授权。
- 并调用下一个中间件函数。
如果您不在当前中间件函数中结束请求/响应循环,则必须调用 next()
函数以将控制权传递给下一个中间件函数
function fn(req, res, next) {
// ...
next();
}
Code language: JavaScript (javascript)
如果您不调用 next()
函数,请求将处于挂起状态。
要在函数中结束请求/响应循环,您需要使用以下方法之一将响应发送回客户端
方法 | 含义 |
---|---|
res.send() | 发送响应主体并结束请求/响应循环 |
res.json() | 发送 JSON 响应并结束请求/响应循环 |
res.redirect() | 将客户端重定向到另一个 URL 并结束请求/响应循环。 |
res.end() | 结束请求/响应循环,不发送任何数据。 |
Express 中间件类型
Express 应用程序可以具有以下类型的中间件
- 应用程序级中间件
- 路由器级中间件
- 内置中间件
- 第三方中间件
- 错误处理中间件
应用程序级中间件
有两种方法可以将应用程序级中间件绑定到 Express 应用程序对象的实例。
首先,将中间件函数传递给 app.use()
函数
import express from 'express';
const app = express();
// define a middleware
const middleware = (req, res, next) {
console.log("Execute the middleware");
next();
}
app.use(middleware);
// ...
Code language: JavaScript (javascript)
其次,将中间件函数传递给 app.METHOD()
函数,例如 app.get()
、app.post()
等
import express from 'express';
const app = express();
// define a middleware
const middleware = (req, res, next) {
console.log("Execute the middleware");
next();
}
app.get('/', middleware, (req, res) => {
// route handler
});
// ...
Code language: JavaScript (javascript)
请注意,路由处理程序也是中间件函数
(req, res) => {
// ...
}
Code language: JavaScript (javascript)
但是,路由处理程序通常通过调用 res.send()
或 res.json()
方法来结束请求/响应循环。因此,您不需要传递 next
函数并在路由处理程序内调用它。
以下示例定义了一个应用程序中间件,该中间件在控制台窗口中记录请求方法和 URL
import express from 'express';
const PORT = process.env.PORT || 3000;
const app = express();
// define a middleware
const log = (req, res, next) => {
console.log(`Request: ${req.method} ${req.url}`);
next();
};
// register the middleware
app.use(log);
// router handlers
app.get('/', (req, res) => {
res.send('Home');
});
app.get('/about', (req, res) => {
res.send('About');
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
Code language: JavaScript (javascript)
它是如何工作的。
首先,定义一个名为 log 的中间件函数,该函数将请求的 URL 和方法显示到控制台
const log = (req, res, next) => {
console.log(`Request: ${req.method} ${req.url}`);
next();
};
Code language: JavaScript (javascript)
其次,使用 app.use()
方法注册中间件
app.use(log);
Code language: JavaScript (javascript)
log 中间件函数将对所有路由(包括 / 和 /about)的每个请求执行。
当您对路径 /
发出 GET
请求时,Express 将执行 log
中间件函数并在控制台中显示日志消息
Request: GET /
Code language: JavaScript (javascript)
类似地,如果您对 /about
路径发出 GET
请求,log
中间件函数将执行并在控制台中显示以下内容
Request: GET /about
Code language: JavaScript (javascript)
请注意,您需要在任何路由处理程序之前注册中间件。否则,中间件将不会生效。例如
import express from 'express';
const PORT = process.env.PORT || 3000;
const app = express();
// define a middleware
const log = (req, res, next) => {
console.log(`Request: ${req.method} ${req.url}`);
next();
};
// router handlers
app.get('/', (req, res) => {
res.send('Home');
});
app.get('/about', (req, res) => {
res.send('About');
});
// register a middleware
app.use(log); // DO NOT RUN for the / and /about routes
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
Code language: JavaScript (javascript)
在此示例中,中间件注册在所有路由处理程序之后。当您请求 /
和 /about
路由时,中间件将不会产生任何影响。
要仅对 /about
方法执行 log 中间件函数,您可以将其传递给相应的路由处理程序,如下所示
// ...
app.get('/about', log, (req, res) => {
res.send('About');
});
// ...
Code language: JavaScript (javascript)
在这种情况下,log 中间件函数仅对路由 /about 的 GET
方法执行。
路由器级中间件
路由器级中间件类似于应用程序级中间件,只是它绑定到 Router 实例而不是 Express 应用程序实例。
我们将在 Express 路由器教程中讨论路由器级中间件。
内置中间件
Express 提供了一些内置的中间件函数
express.json
中间件允许您解析具有 JSON 主体的请求。(自 Express4.16.0
及更高版本可用)。express.static
中间件提供静态资产,例如 HTML 文件、图像等。express.urlencoded
解析具有 URL 编码主体的请求。
第三方中间件
有许多第三方中间件可用。第三方中间件允许您增强 Express 应用程序的功能。
第三方中间件需要通过包管理器(如 npm)进行安装。我们将在后续教程中向您介绍一些最常用的第三方中间件。
错误处理中间件
与常规中间件不同,错误处理中间件采用四个参数而不是三个
function fn(err, req, res, next) {
// ...
}
Code language: JavaScript (javascript)
错误处理中间件的第一个参数是一个错误对象。我们将在错误处理教程中讨论错误处理中间件。
总结
- 中间件是一个可以访问请求、响应和下一个中间件函数的函数。
- 使用
app.use()
函数注册中间件。 - 在特定路由处理程序之前注册中间件,以将中间件应用于这些路由处理程序。