事件处理程序

¥Event Handlers

事件处理程序是一个接收 H3Event 并返回响应的函数。

¥An event handler is a function that receives an H3Event and returns a response.

你可以使用 defineHandler 定义类型化事件处理程序。

¥You can define typed event handlers using defineHandler.

import { H3, defineHandler } from "h3";

const app = new H3();

const handler = defineHandler((event) => "Response");

app.get("/", handler);
使用 defineHandler 是可选的。你也可以使用一个接受 H3Event 并返回响应的函数。¥!NOTE Using defineHandler is optional. You can instead, simply use a function that accepts an H3Event and returns a response.

回调函数可以是同步的,也可以是异步的:

¥The callback function can be sync or async:

defineHandler(async (event) => "Response");

对象语法

¥Object Syntax

中间件

¥middleware

你可以选择注册一些 中间件 以与事件处理程序一起运行,从而拦截请求、响应或错误。

¥You can optionally register some middleware to run with event handler to intercept request, response or errors.

import { basicAuth } from "h3";

defineHandler({
  middleware: [basicAuth({ password: "test" })],
  handler: (event) => "Hi!",
});
Read more in Response Handling.
Read more in Guide > API > H3event.

meta

你可以定义附加到处理程序的可选路由元数据,并从任何其他中间件访问它们。

¥You can define optional route meta attached to handlers, and access them from any other middleware.

import { H3, defineHandler } from "h3";

const app = new H3();

app.use((event) => {
  console.log(event.context.matchedRoute?.meta); // { tag: "admin" }
});

app.get("/admin/**", defineHandler({
  meta: { tag: "admin" },
  handler: (event) => "Hi!",
})
在将路由注册到应用实例时,也可以添加路由元信息。

处理程序 .fetch

¥Handler .fetch

使用 defineHandler 定义的事件处理程序无需使用 H3 类即可充当 Web 处理程序。

¥Event handlers defined with defineHandler, can act as a web handler without even using H3 class.

const handler = defineHandler(async (event) => `Request: ${event.req.url}`);

const response = await handler.fetch("http://localhost/");
console.log(response, await response.text());

惰性处理程序

¥Lazy Handlers

你可以使用 defineLazyEventHandler 定义延迟事件处理程序。这允许你定义一些一次性逻辑,这些逻辑仅在收到第一个与路由匹配的请求时执行一次。

¥You can define lazy event handlers using defineLazyEventHandler. This allow you to define some one-time logic that will be executed only once when the first request matching the route is received.

惰性事件处理程序必须返回事件处理程序。

¥A lazy event handler must return an event handler.

import { defineLazyEventHandler } from "h3";

defineLazyEventHandler(async () => {
  await initSomething(); // Will be executed only once
  return (event) => {
    return "Response";
  };
});

这在定义一些一次性逻辑(例如配置、类初始化、繁重计算等)时非常有用。

¥This is useful to define some one-time logic such as configuration, class initialization, heavy computation, etc.

另一个用例是延迟加载路由块:

¥Another use-case is lazy loading route chunks:

import { H3, defineLazyEventHandler } from "h3";

const app = new H3();

app.all(
  "/route",
  defineLazyEventHandler(() =>
    import("./route.mjs").then((mod) => mod.default),
  ),
);

转换为处理程序

¥Converting to Handler

在某些情况下,你可能需要将 Node.js 或其他框架编写的事件处理程序或实用程序转换为 H3。有一些内置实用程序可以执行此操作。

¥There are situations that you might want to convert an event handler or utility made for Node.js or another framework to H3. There are built-in utils to do this.

来自 Web 处理程序

¥From Web Handlers

带有 请求 => 响应 签名的请求处理程序可以使用 fromWebHandler 实用程序或 H3.mount 转换为 H3 事件处理程序。

¥Request handlers with Request => Response signuture can be converted into H3 event handlers using fromWebHandler utility or H3.mount.

import { H3, fromWebHandler } from "h3";

export const app = new H3();

const webHandler = (request) => new Response("👋 Hello!"));

// Using fromWebHandler utiliy
app.all("/web", fromWebHandler(webHandler));

// Using simple wrapper
app.all("/web", event => webHandler(event.req));

// Using app.mount
app.mount("/web", webHandler)

来自 Node.js 处理程序

¥From Node.js Handlers

如果你有一个为 Node.js 编写的带有 (req, res) => {} 语法的旧式请求处理程序,则可以使用 fromNodeHandler 将其转换为 H3 事件处理程序。

¥If you have a legacy request handler with (req, res) => {} syntax made for Node.js, you can use fromNodeHandler to convert it to an h3 event handler.

Node.js 事件处理程序只能在 Node.js 服务器运行时中运行!¥!IMPORTANT Node.js event handlers can only run within Node.js server runtime!
import { H3, fromNodeHandler } from "h3";

// Force using Node.js compatibility (also works with Bun and Deno)
import { serve } from "h3/node";

export const app = new H3();

const nodeHandler = (req, res) => {
  res.end("Node handlers work!");
};

app.get("/web", fromNodeHandler(nodeHandler));