Nitro 服务端入口
使用服务端入口处理没有匹配到任何路由的请求
服务端入口是 Nitro 注册为 catch-all(/**)路由的特殊处理器。特定路由始终具有优先权,因此服务端入口只会在请求没有匹配到任何路由时、渲染器运行之前执行。它通常用于在 Nitro 中挂载另一个框架,或为文件系统路由未处理的所有请求实现自定义路由。
Warning
服务端入口是回退机制,而不是全局中间件:对于已由路由处理的请求,它不会运行。对于必须应用于每个请求的横切关注点(身份验证、日志记录、请求预处理),请改用中间件。
#自动检测的 server.ts
默认情况下,Nitro 会在 serverDir(如果已设置)或项目根目录中自动查找 server.ts(或 .js、.mjs、.mts、.tsx、.jsx)文件。
如果找到,Nitro 将使用它作为服务端入口,并针对所有传入请求运行它。
export default {
async fetch(req: Request) {
const url = new URL(req.url);
// 处理特定路由
if (url.pathname === "/health") {
return new Response("OK", {
status: 200,
headers: { "content-type": "text/plain" }
});
}
// 为所有请求添加自定义请求头
// 不返回内容以继续执行下一个处理器
}
}Tip
当检测到 server.ts 时,Nitro 会在终端中输出:已检测到 `server.ts` 作为服务端入口。
使用此配置:
/health→ 由服务端入口处理(返回响应)/api/hello→ 由 API 路由处理器直接处理/about等 → 服务端入口先运行,如果没有返回响应,则继续执行到渲染器
#框架兼容性
服务端入口是与其他框架集成的绝佳方式。任何公开标准 Web fetch(request: Request): Response 接口的框架都可以用作服务端入口。
#Web 兼容框架
实现 Web fetch API 的框架可以直接与 server.ts 配合使用:
import { H3 } from "h3";
const app = new H3()
app.get("/", () => "⚡️ 来自 H3 的问候!");
export default app;#Node.js 框架
对于使用 (req, res) 风格处理器(如 Express 或 Fastify)的 Node.js 框架,请将服务端入口文件命名为 server.node.ts 而不是 server.ts。Nitro 将自动检测 .node. 后缀,并使用 srvx 将 Node.js 处理器转换为兼容 Web 的 fetch 处理器。
import Express from "express";
const app = Express();
app.use("/", (_req, res) => {
res.send("Hello from Express with Nitro!");
});
export default app;#服务端选项
当服务端入口的默认导出为普通对象时,以下服务端选项会传递给由 Node.js、Bun 和 Deno 预设启动的 srvx 服务器:port、hostname、reusePort、protocol、tls、silent、gracefulShutdown、maxRequestBodySize、trustProxy 以及运行时特定设置(node、bun、deno)。
使用 defineServerEntry 辅助函数获取类型化选项:
import { defineServerEntry } from "nitro";
export default defineServerEntry({
fetch(req) {
return new Response("Hello from server entry!");
},
port: 8080,
maxRequestBodySize: 1024 * 1024,
});Note
NITRO_PORT/PORT、NITRO_HOST/HOST和NITRO_SSL_CERT/NITRO_SSL_KEY环境变量的优先级高于port、hostname和tls选项,因此服务器仍可在运行时进行配置。- 在开发过程中(
nitro dev),选项会应用于开发工作进程服务器,但监听器选项(port、hostname、protocol、tls、silent、gracefulShutdown)除外,这些选项由开发服务器和 CLI(--port、--host)控制。Vite 开发服务器不会应用这些选项。 - 其他 srvx 选项(
middleware、plugins、error和manual)会被忽略。这些选项会改变请求的处理方式,但只适用于这些预设,不适用于无服务器部署或nitroApp.fetch。请改用 Nitro 中间件和插件。 - 选项只会从普通对象导出中读取(不会从
export default app这类框架实例中读取),也不会从 Node.js 格式入口(server.node.ts)中读取。
#配置
#自定义服务端入口文件
你可以使用 Nitro 配置中的 serverEntry 选项指定自定义服务端入口文件:
import { defineConfig } from "nitro";
export default defineConfig({
serverEntry: "./nitro.server.ts"
})你还可以提供一个包含 handler 和 format 选项的对象:
import { defineConfig } from "nitro";
export default defineConfig({
serverEntry: {
handler: "./server.ts",
format: "node" // "web"(默认)或 "node"
}
})#处理器格式
format 选项控制 Nitro 如何处理服务端入口的默认导出:
"web"(默认):要求使用具有fetch(request: Request): Response方法的 Web 兼容处理器"node":要求使用 Node.js 风格的(req, res)处理器。Nitro 会自动将其转换为 Web 兼容处理器
自动检测时,格式由文件名决定:server.node.ts 使用 "node" 格式,而 server.ts 使用 "web" 格式。
#禁用服务端入口
将 serverEntry 设置为 false 以禁用自动检测,并阻止 Nitro 使用任何服务端入口:
import { defineConfig } from "nitro";
export default defineConfig({
serverEntry: false
})#使用事件处理器
你可以导出使用 defineHandler 创建的事件处理器,而不是 Web fetch 处理器,从而获得更好的类型推断并访问 H3 事件对象:
import { defineHandler, HTTPError } from "nitro";
export default defineHandler((event) => {
// 仅在请求未匹配到任何路由时运行
if (event.url.pathname.startsWith("/api/")) {
throw new HTTPError("Unknown API endpoint", { status: 404 });
}
// 为渲染器添加上下文
event.context.requestId = crypto.randomUUID();
// 不返回内容以将请求交给渲染器
});Important
返回 undefined(或不返回任何内容)会将请求交给渲染器。如果没有渲染器,Nitro 会返回一个空的 200 响应。返回一个值则会在此处结束请求。
#启动逻辑
服务端入口会被预先导入,因此其中的顶层代码会在服务器启动时运行一次,而不是在第一个请求到达时运行。
请注意:
- 顶层代码会在运行时插件之前运行,因此插件注册的钩子尚不可用。不要在顶层调用
useNitroApp();应在处理器内部调用它 - 顶层
await会延迟启动:在服务端入口完成求值之前,服务器不会接受请求 - 在无服务器和边缘预设中,“启动”意味着新实例的每次冷启动。某些运行时(例如 Cloudflare Workers)不允许在全局作用域中执行 I/O(例如
fetch) - 在开发过程中,每当服务端入口重新加载时,顶层代码都会再次运行
#请求生命周期
服务端入口被注册为通配符(/**)路由处理器。当特定路由(如 /api/hello)匹配到请求时,该路由处理器具有优先权。对于不匹配任何特定路由的请求,服务端入口在渲染器之前运行:
1. Server hook: `request`
2. Route rules (headers, redirects, etc.)
3. Global middleware (static assets first, then middleware/)
4. Route-scoped middleware (handlers config)
5. Route matching:
a. Specific routes (routes/) ← if matched, handles the request
b. Server entry ← runs for unmatched routes
c. Renderer (renderer.ts or index.html)当服务端入口和渲染器同时存在时,它们会串联执行:服务端入口先运行,如果没有返回响应,则由渲染器处理请求。
#开发模式
在开发过程中,Nitro 会监视服务端入口文件的变更。当文件被创建、修改或删除时,开发服务器会自动重新加载以获取最新更改。