中间件
Express框架中,中间件用于拦截所有或部分请求,并对这部分请求和响应上下文进行统一处理。中间件的概念类似Java中的拦截器或过滤器,常用于实现日志记录、身份验证、请求解析等通用功能。
中间件的基本概念
中间件本质上是一个函数,它可以访问请求对象req、响应对象res以及next函数。中间件可以执行以下操作:
- 执行代码逻辑
- 修改请求和响应对象
- 结束请求响应循环
- 调用下一个中间件
下面是一个最简单的中间件示例。
const myMiddleware = (req, res, next) => {
console.log("middleware handled");
next();
};
注意:中间件中如果需要将请求继续向下一个处理函数传递,必须调用next()方法;如果是实现类似登录拦截的功能,则直接响应请求即可,无需调用next()。
注册中间件
全局中间件
使用app.use()可以注册全局中间件,它会拦截所有请求。
import express from "express";
const app = express();
// 注册全局中间件
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
app.listen(3000);
路径前缀中间件
中间件中可以指定路径前缀,此时只会匹配该前缀开头的请求。
app.use("/api", (req, res, next) => {
console.log("API request");
next();
});
注意:使用app.use()注册中间件时,指定的路径是前缀匹配的。
路由级中间件
中间件也可以只应用于特定路由,下面例子代码中,authMiddleware只对/protected生效。
const authMiddleware = (req, res, next) => {
if (req.headers.authorization) {
next();
} else {
res.status(401).json({ error: "Unauthorized" });
}
};
app.get("/protected", authMiddleware, (req, res) => {
res.json({ message: "Protected data" });
});
中间件执行顺序
中间件按照注册顺序依次执行。
import express from "express";
const app = express();
app.use((req, res, next) => {
console.log("First middleware");
next();
});
app.use((req, res, next) => {
console.log("Second middleware");
next();
});
app.get("/", (req, res) => {
res.send("Hello");
});
app.listen(3000);
内置中间件
Express框架包含了几个实用的内置中间件。
解析请求体中间件
Express提供了解析JSON和URL编码请求体的内置中间件。
import express from "express";
const app = express();
// 解析 JSON 请求体
app.use(express.json());
// 解析 URL 编码的请求体
app.use(express.urlencoded({ extended: true }));
app.post("/data", (req, res) => {
console.log(req.body);
res.json({ received: req.body });
});
app.listen(3000);
静态资源中间件
静态资源中间件可以指定一个路径,其中的文件会以静态资源的方式提供。
import express from "express";
import path from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const app = express();
app.use("/static", express.static(path.join(__dirname, "static")));
app.listen(3000);
其中/static是路径前缀,比如服务器上指定文件夹里有一个1.txt文件,那么它的URL路径就是/static/1.txt。
注意:在ESM模块中,__dirname不能直接使用,需要通过import.meta.url手动计算获取。
错误处理中间件
Express支持一个特殊的错误处理中间件,它需要4个参数:err、req、res、next。
import express from "express";
const app = express();
app.get("/error", (req, res, next) => {
const err = new Error("Something went wrong");
next(err);
});
// 错误处理中间件(必须有4个参数)
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: err.message });
});
app.listen(3000);
Express框架会自动捕捉HTTP请求处理中的异常,交给错误处理中间件进行处理,注意错误处理中间件应该在路由之后注册。
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。