---
title: "服务器导入"
description: "`nuxt/server` 是服务器代码的导入接口，不依赖特定服务器运行时。"
canonical_url: "https://nuxt.zhcndoc.com/docs/4.x/guide/going-further/server-imports"
---
# 服务器导入

> \`nuxt/server\` 是服务器代码的导入接口，不依赖特定服务器运行时。

Nuxt 可以使用不同的[服务器构建器](https://nuxt.zhcndoc.com/docs/4.x/guide/going-further/builders)：Nitro 2（`nitropack`，Nuxt 3 和 4 中的默认选项）、Nitro 3（`nitro`，从 Nuxt 5 开始），或直接使用 Vite。

`nuxt/server` 提供与特定服务器运行时无关的服务器代码通用工具。它是 Nuxt 的第二个运行时接口，与 `nuxt/app`（也可以通过 `#app` 访问）并列；后者用于应用中也会在浏览器运行的部分。

```ts [server/api/hello.ts]
import { defineEventHandler, getQuery } from 'nuxt/server'

export default defineEventHandler((event) => {
  const { name } = getQuery<{ name?: string }>(event)
  return { message: `Hello, ${name ?? 'world'}!` }
})
```

这段代码可以在 `@nuxt/nitro-server` 和 `@nuxt/vite-server` 下运行；即使 h3 或 Nitro 升级主版本，也能继续运行，因为 Nuxt 会集中处理这些变化。

`nuxt/server` 从 Nuxt 4.6 开始提供，因此一个文件就能同时用于运行 `nitropack` v2 的 Nuxt 4.6、运行 Nitro v3 的 Nuxt 5，以及未来构建器带来的任何环境。

::tip
每个 Nuxt 应用都安装了 `nuxt`，因此 `nuxt/server` 无需别名或额外依赖即可解析。导入它的模块无需依赖 h3 或 Nitro 的 peer dependency。
::

## 类型和工具

| 导入                                                       | 用途                                                                                                                  |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `defineEventHandler`                                     | 定义请求处理程序。                                                                                                           |
| `createError`、`isNuxtError`                              | 创建并识别 HTTP 错误。                                                                                                      |
| `getRequestURL`、`getRequestHost`、`getRequestProtocol`    | 获取请求的 URL、主机和协议。仅在你控制且会覆盖这些请求头的代理之后，才传入 `{ xForwardedHost: true, xForwardedProto: true }` 来信任对应的转发标头。               |
| `getRequestHeader`、`getRequestHeaders`                   | 读取请求标头。                                                                                                             |
| `getRouterParam`、`getRouterParams`                       | 读取与请求匹配的动态路径段。                                                                                                      |
| `getRequestIP`                                           | 获取客户端 IP 地址，[请求中会信任转发标头](#client-ip)。                                                                               |
| `getQuery`、`getValidatedQuery`                           | 读取查询字符串，可选择进行[校验](#validation)。                                                                                     |
| `readBody`、`readValidatedBody`                           | 读取并解析请求体，可选择进行[校验](#validation)。                                                                                    |
| `getCookie`、`parseCookies`、`setCookie`、`deleteCookie`    | 读取单个或全部 Cookie，以及写入 Cookie。                                                                                         |
| `setResponseStatus`                                      | 设置响应状态和原因短语。                                                                                                        |
| `handleCors`                                             | 应用 [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) 标头并响应预检请求。                                 |
| `sendRedirect`                                           | 重定向请求。                                                                                                              |
| `serverFetch`                                            | 在进程内获取应用的路由，路径相对于 `app.baseURL`，并转发 `cookie` 和 `authorization` 标头（除非设置 `forwardHeaders`）。在不支持进程内 fetch 的服务器构建器上会拒绝。 |
| `useSession`、`getSession`、`updateSession`、`clearSession` | 读取和写入[密封的会话 Cookie](#sessions)。                                                                                     |
| `deriveSecret`                                           | 从 `appSecret` [派生用途专属的密钥](#deriving-secrets)。                                                                       |
| `getRouteRules`、`matchRouteRules`                        | 获取请求匹配的[路由规则](https://nuxt.zhcndoc.com/docs/4.x/guide/concepts/rendering#route-rules)，或获取其他路径匹配的规则。                 |
| `useRuntimeConfig`                                       | 获取服务器的[运行时配置](https://nuxt.zhcndoc.com/docs/4.x/guide/going-further/runtime-config)。                                |
| `useServerHooks`                                         | 获取服务器运行时钩子，包括 `render:html` 等渲染器钩子，以及 `NuxtServerHooks` 中声明的钩子。                                                     |
| `useAppConfig`                                           | 获取[应用配置](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/app/app-config)；传入事件时，每个请求都会得到一份副本。                  |

工具旁还导出了以下类型：`RequestEvent`、`RequestEventContext`、`NuxtRequestEvent`、`EventHandler`、`AppRouteRules`、`ServerRoutes`、`CorsOptions`、`ValidateResult`、`NuxtError`、`NuxtErrorDetails`、`NuxtErrorJSON`、`NuxtErrorLike`、`Session`、`SessionConfig`、`SessionData`、`SessionEvent`、`SessionManager`、`SessionPassword` 和 `SessionUpdate`。

这些名称不会从 `nuxt/server` 自动导入。在服务器代码中，同名的[自动导入项](https://nuxt.zhcndoc.com/docs/4.x/directory-structure/server)是 h3 自身的辅助函数，它们接收 h3 event，且部分行为有所不同（例如 `defineEventHandler`、`handleCors`、`getRouterParams` 和 `readValidatedBody`），因此请显式从 `nuxt/server` 导入。其中也包括 `defineEventHandler`：`nuxt/server` 中的辅助函数会读取它传给处理程序的 event。

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/getting-started/upgrade#moving-to-nuxtserver"}
了解如何将现有服务器代码迁移到 `nuxt/server`，以及它的辅助函数与 h3 的辅助函数有何不同。
::

::tip
`defineEventHandler` 会保留处理程序的返回类型，而这正是路由的 [`$fetch` 和 `useFetch`](https://nuxt.zhcndoc.com/docs/4.x/getting-started/data-fetching) 调用以及对其调用 `serverFetch` 时的 `response.json()` 所需的类型。请为返回值添加类型注解，而不是为处理程序添加。
::

## Event

`RequestEvent` 是 `nuxt/server` 工具操作所依据的 event，其中包含请求、请求 URL、待发送的响应以及请求上下文。

```ts
interface RequestEvent {
  readonly req: Request
  url: URL
  readonly res: { status?: number, statusText?: string, readonly headers: Headers }
  readonly context: RequestEventContext
}
```

要设置、读取、追加或移除响应标头，请直接使用 `event.res.headers`：它是标准的 `Headers` 对象。

Nitro 还提供了更多内容，例如 `event.node` 和 `event.waitUntil()`；但这四个核心属性适用于所有运行时，无需使用辅助函数：

```ts [server/api/echo.post.ts]
export default defineEventHandler(async (event) => {
  const { id } = await event.req.json()
  return { id, page: event.url.searchParams.get('page') }
})
```

`NuxtRequestEvent` 是配置的构建器所提供形态的同一个请求；在 `@nuxt/nitro-server` 下，它是 h3 v1 的 `H3Event`。

## 处理程序

处理程序文件必须默认导出 `nuxt/server` 中 `defineEventHandler` 的返回值。直接导出函数，或使用 h3 的 `defineEventHandler` 包装函数，收到的会是服务器运行时自己的 event。

处理程序可以返回：

- 可 JSON 序列化的值，作为 JSON 发送，并使用设置在 `event.res` 上的状态和标头。
- `Response`，使用其自身状态发送。设置在 `event.res.headers` 上的标头也会发送，并且会保留两处设置的 `set-cookie` 值。
- `ReadableStream`，作为响应正文流式发送。

## 验证

`readValidatedBody` 和 `getValidatedQuery` 接受任意 [Standard Schema](https://standardschema.dev)（Zod、Valibot、ArkType 等），也接受返回已验证值的函数；返回 `true` 表示接受输入，返回 `false` 则表示拒绝输入。

```ts [server/api/users.post.ts]
import { defineEventHandler, readValidatedBody } from 'nuxt/server'
import { z } from 'zod'

export default defineEventHandler(async (event) => {
  const user = await readValidatedBody(event, z.object({ name: z.string() }))
  return { created: user.name }
})
```

无效输入会被拒绝，并返回 `400` 错误；其 `data.issues` 会列出验证失败的内容。传入 `onError` 可以使用其他错误来拒绝输入。

## 客户端 IP

`getRequestIP(event)` 返回服务器运行时报告的连接地址；如果没有报告地址，则返回 `undefined`。默认情况下，不会信任任何转发标头，因为客户端可以在其中发送任意值。

在你控制的代理后面，可以传入 `{ xForwardedFor: true }`，改为读取 `X-Forwarded-For` 的第一个条目。仅当代理会覆盖该标头时才这样做：如果代理只是追加内容，客户端发送的值仍会排在最前面。

## 会话

`useSession` 会读取请求的会话；如果没有可读取的会话，就会将新会话密封到 Cookie 中。数据使用 [iron](https://github.com/brc-dd/iron-webcrypto) 密封，因此数据存放在 Cookie 中，而非服务器存储中；Cookie 默认使用 `httpOnly`、`secure`、`sameSite: 'lax'` 和 `path: '/'`。

```ts [server/api/visits.ts]
import { defineEventHandler, useSession } from 'nuxt/server'

export default defineEventHandler(async (event) => {
  const session = await useSession<{ visits: number }>(event)
  await session.update(data => ({ visits: (data.visits ?? 0) + 1 }))
  return { visits: session.data.visits }
})
```

如果没有设置 `password`，会话会使用从应用的 [`appSecret`](https://nuxt.zhcndoc.com/docs/4.x/guide/going-further/runtime-config#application-secret) 派生的密钥进行密封，因此只需设置 `NUXT_APP_SECRET`。传入至少 32 个字符的 `password`，即可改用你自己的密钥进行密封。设置 `maxAge`（以秒为单位）可使 Cookie 和密封值同时过期；设置 `name` 可将 Cookie 名称从 `nuxt-session` 更改为其他名称；设置 `cookie` 可覆盖任意 Cookie 属性。

每个请求只会解封一次会话，因此你可以在任意多个位置调用 `getSession`。`updateSession` 和 `clearSession` 是不使用 manager 对象的同类操作。

### 派生密钥

`deriveSecret(purpose)` 会从 `appSecret` 派生特定用途的密钥：32 字节，以十六进制编码，只要 `appSecret` 未更改就保持稳定，并且每个用途的密钥都各不相同。会话辅助函数使用的就是它；模块也应使用它，而不是自行请求密钥。请将用途命名为其所属对象的命名空间。

```ts
import { deriveSecret } from 'nuxt/server'

const password = await deriveSecret('my-module:tokens')
```

如果未设置 `appSecret`，或其长度少于 32 个字符，就会抛出一个提及 `NUXT_APP_SECRET` 的 `500` 错误。

::note
h3 提供了同名的会话辅助函数；在 `@nuxt/nitro-server` 下，自动导入的 `useSession`、`getSession`、`updateSession` 和 `clearSession` 会解析为这些函数，因此请显式从 `nuxt/server` 导入。它们是不同的实现，不能互换：h3 默认的 Cookie 名称是 `h3` 而非 `nuxt-session`，使用自己的配置，并且其中一个实现签发的会话无法由另一个实现解封。
::

::note
会话 API 稳定，但密封 Cookie 的格式可能会在次要版本中更改：Nuxt 计划在 `iron-webcrypto` 发布基于 AES-GCM 的密封方式后迁移到该方式。届时，现有会话会以旧格式读取，并在下次写入时以新格式重新密封，因此用户不会被登出。密封值与 h3 的 `useSession` 生成的值不可互换。
::

::warning
会话存放在 Cookie 中，因此大小受浏览器可接受范围的限制。写入序列化后超过 4096 字节的会话会抛出错误；较大的数据应保存在服务器端，并通过 ID 在会话中引用。
::

## 超出接口范围

`nuxt/server` 不是 h3 的重新导出，因此如果你需要 h3 和 Nitro 提供的其他功能（例如服务器生命周期相关功能，如 `defineNitroPlugin` 和 `defineNitroErrorHandler`，或 Nitro 自己的运行时钩子），应直接导入。

如果处理程序需要 h3 自带的辅助函数（例如 `readRawBody`、`readMultipartFormData`、`assertMethod`、`proxyRequest`、`fetchWithEvent` 或 `writeEarlyHints`），或者会读取 `event.node` 或 `event.waitUntil()`，请从 `h3` 为该处理程序导入 `defineEventHandler`：

```ts [server/api/upload.post.ts]
import { defineEventHandler, readMultipartFormData } from 'h3'

export default defineEventHandler(async (event) => {
  const parts = await readMultipartFormData(event)
  return { received: parts?.length ?? 0 }
})
```

Nitro 自己的 API 大多不需要传入 event：`defineCachedEventHandler()`、`useStorage()`、`useDatabase()` 和 tasks。请从 `nitropack/runtime` 导入它们。

## 不具备可移植性的内容

以下功能需要使用 `nuxt/server` 之外的内容，因为 Nuxt 无法为每个构建器都提供这些功能：

- **存储。** `useStorage()` 来自 `nitropack/runtime`，其背后的 driver 配置也来自这里。
- **缓存。** `defineCachedEventHandler()` 和 `defineCachedFunction()` 来自 `nitropack/runtime`。要使用能在任何环境运行的缓存，请直接依赖缓存库。
- **服务器插件。** `defineNitroPlugin()` 来自 `nitropack/runtime`。在插件中，`nuxt/server` 的 `useServerHooks()` 可注册渲染器钩子（包括 `render:html`）以及 `NuxtServerHooks` 中声明的钩子；Nitro 自己的 `request`、`beforeResponse` 和 `error` 等钩子则来自 `nitropack/runtime` 中的 `useNitroApp().hooks`。
- **惰性处理程序。** `lazyEventHandler()` 来自 `h3`。

## 仅限服务器代码

在 Vue 组件、插件或 `shared/` 目录中导入 `nuxt/server` 会导致构建失败；错误会提示你改用 `#app`、`#imports`、`$fetch` 和 `useFetch`。这些上下文仍可解析其类型，因此 `$fetch` 能知道服务器路由会返回什么。

`nuxt/server` 也只能用于由服务器构建器打包的代码，因为构建器会提供其背后的运行时配置、应用配置、钩子和进程内 fetch。在 Nuxt 进程中运行的代码（例如 `nuxt.config.ts`、模块的 `setup`，或传给 `addDevServerHandler` 的函数）并不具备这些能力，因此不要在那里导入 `nuxt/server`：例如，`useRuntimeConfig()` 和 `useAppConfig()` 会返回空对象。请改为读取 `nuxt.options`，并参阅[开发服务器处理程序](https://nuxt.zhcndoc.com/docs/4.x/guide/modules/server-compatibility#dev-server-handlers)了解如何在模块中编写处理程序。

## 模块

运行时代码仅从 `nuxt/server` 导入内容的模块，从 v4.6 起可在任何服务器构建器下运行，无需版本检查，也不依赖 h3 或 Nitro：

```ts [runtime/server/api/status.ts]
import { defineEventHandler, useRuntimeConfig } from 'nuxt/server'

export default defineEventHandler(() => ({
  version: useRuntimeConfig().myModule.version,
}))
```

::tip
打包时请将 `nuxt/server` 保留为外部依赖；它会在 Nuxt 构建过程中解析为正确的服务器构建器工具。
::

支持 Nuxt <4.6 版本需要多做一步，因为这些项目无法解析 `nuxt/server`。你可以同时注册可移植文件和当前随包发布的文件，Nuxt 会选择应用能够运行的文件。

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/guide/modules/server-compatibility"}
了解如何为每个服务器 API 注册一个处理程序。
::

::read-more{to="https://nuxt.zhcndoc.com/docs/4.x/guide/going-further/builders"}
了解服务器构建器如何提供 `nuxt/server` 背后的实现。
::

---

- [源码](https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/server/index.ts)


## Sitemap

See the full [sitemap](https://nuxt.zhcndoc.com/sitemap.md) for all pages.
