# 中间件
> 使用 H3 中间件拦截请求、响应和错误。
我们建议尽可能使用组合式工具。全局中间件可能会让应用逻辑变得更复杂,降低其可预测性和理解难度。
全局中间件在每个请求路由处理之前运行,作为包装器来拦截请求、响应和错误。
你可以使用 [`H3.use`](/guide/api/h3#h3use) 向 [app 实例](/guide/api/h3) 注册全局中间件。
**示例:** 注册一个记录每个请求的全局中间件。
```js
app.use((event) => {
console.log(event);
});
```
**示例:** 注册一个匹配特定请求的全局中间件。
```js
app.use(
"/blog/**",
(event, next) => {
console.log("[alert] POST 请求访问 /blog 路径!");
},
{
method: "POST",
// match: (event) => event.req.method === "POST",
},
);
```
你可以注册带有 `next` 参数的中间件,以拦截后续中间件和处理器的返回值。
```js
app.use(async (event, next) => {
const rawBody = await next();
// [拦截响应]
return rawBody;
});
```
下面示例中,总是响应 `Middleware 1`。
```js
app
.use(() => "Middleware 1")
.use(() => "Middleware 2")
.get("/", "Hello");
```
如果中间件返回除 `undefined` 或 `next()` 结果之外的值,中间件会立即拦截请求处理并发送响应。
在添加路由时,可以注册只随该路由运行的中间件。
```js
import { basicAuth } from "h3";
app.get(
"/secret",
(event) => {
/* ... */
},
{
middleware: [basicAuth({ password: "test" })],
},
);
```
为方便起见,H3 提供了中间件工厂函数 `onRequest`、`onResponse` 和 `onError`:
```js
import { onRequest, onResponse, onError } from "h3";
app.use(
onRequest((event) => {
console.log(`[${event.req.method}] ${event.url.pathname}`);
}),
);
app.use(
onResponse((response, event) => {
console.log(`[${event.req.method}] ${event.url.pathname} ~>`, body);
}),
);
app.use(
onError((error, event) => {
console.log(
`[${event.req.method}] ${event.url.pathname} !! ${error.message}`,
);
}),
);
```