在 Express 里,中间件是具备访问请求对象(`req`)、响应对象(`res`)以及应用程序请求-响应循环中的下一个中间件函数(一般用`next`表示)的函数。
一、中间件的定义与调用顺序
在 Express 应用中,中间件按照它们被定义的顺序依次执行。若一个中间件调用了 `next()` 函数,请求就会传递给下一个中间件;若没有调用 `next()`,请求处理流程会在此处停止。
javascript
const middleware = (req, res, next) => {
// 在这里可以执行一些操作,如日志记录、身份验证等
next(); // 调用 next() 函数将控制权传递给下一个中间件或路由处理函数
};
二、中间件的作用
请求预处理:中间件可在请求到达路由处理函数之前对请求进行处理,例如解析请求体、验证请求参数、记录请求日志等。
响应处理:可在响应发送给客户端之前对响应进行处理,例如设置响应头、格式化响应数据等。
错误处理:专门的错误处理中间件能够捕获和处理应用程序中的错误,避免程序崩溃,并向客户端返回合适的错误信息。
身份验证与授权:用于验证用户身份和权限,确保只有经过授权的用户才能访问特定的路由或资源。
三、中间件的使用方式
1. 应用级中间件
通过 `app.use()` 或 `app.METHOD()`(如 `app.get()`、`app.post()` 等)将中间件应用到整个应用或特定的路由上。
javascript
const express = require("express");
const app = express();
// 应用级中间件,对所有请求生效
app.use((req, res, next) => {
console.log("This is an application-level middleware");
next();
});
// 应用到特定路由的中间件
app.get(
"/",
(req, res, next) => {
console.log("This middleware is applied to the root route");
next();
},
(req, res) => {
res.send("Hello, World!");
}
);
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
2. 路由级中间件
与应用级中间件类似,但它是通过路由实例来使用的。
javascript
const express = require("express");
const app = express();
const router = express.Router();
// 路由级中间件
router.use((req, res, next) => {
console.log("This is a router-level middleware");
next();
});
router.get("/", (req, res) => {
res.send("Hello from the router!");
});
app.use("/router", router);
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
3. 错误处理中间件
错误处理中间件有四个参数 `(err, req, res, next)`,用于捕获和处理应用程序中的错误。
javascript
const express = require("express");
const app = express();
app.get("/", (req, res) => {
throw new Error("Something went wrong!");
});
// 错误处理中间件
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send("Internal Server Error");
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});
4. 第三方中间件
可以使用第三方中间件来增强 Express 应用的功能,例如 `body-parser` 用于解析请求体,`morgan` 用于记录请求日志。
javascript
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const morgan = require("morgan");
// 使用 morgan 中间件记录请求日志
app.use(morgan("dev"));
// 使用 body-parser 中间件解析请求体
app.use(bodyParser.json());
app.post("/data", (req, res) => {
console.log(req.body);
res.send("Data received");
});
app.listen(3000, () => {
console.log("Server is running on port 3000");
});