# Nuxt HTTP 请求生命周期 当一个 HTTP 请求发送到 Nuxt 应用时,它会经过一系列步骤,下面是完整的请求生命周期: ## 服务器端处理 ### 1. Nitro 服务器初始化(仅一次) - Nitro 服务器启动并初始化 `/server/plugins` 目录下的插件 - 这些插件只在服务器启动时执行一次 - 在无服务器环境中,每个请求都会启动服务器,但插件不会被等待执行完成 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-1-setup-nitro-server-and-nitro-plugins-once) ### 2. Nitro 服务器中间件 - 对于每个请求,执行 `server/middleware/` 下的中间件 - 这些中间件可用于身份验证、日志记录或请求转换 - 如果中间件返回值,请求将终止并将返回值作为响应 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-2-nitro-server-middleware) ### 3. 请求路由分发 根据请求路径,Nitro 将请求分发到不同的处理程序: - 如果请求路径匹配 `/api/*`,则路由到 API 处理程序(`server/api/` 目录) - 如果请求路径匹配 `server/routes/` 中定义的路由,则路由到相应的处理程序 - 如果是页面请求,则继续 Nuxt 应用的初始化 [服务器目录结构](https://nuxt.com/docs/guide/directory-structure/server) ### 4. API 处理(如果是 API 请求) - 如果请求匹配 `server/api/` 目录中的路由,相应的处理程序将被执行 - 处理程序可以直接返回 JSON 数据、Promise 或使用 `event.node.res.end()` 发送响应 - API 处理完成后,请求结束,不会继续到 Vue 应用 [服务器 API](https://nuxt.com/docs/guide/directory-structure/server) ### 5. Nuxt 应用初始化(如果是页面请求) - 创建 Vue 和 Nuxt 实例 - 执行 Nuxt 服务器插件,包括内置插件和 `plugins/` 目录中的自定义插件 - 调用 `app:created` 钩子 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-3-initialize-nuxt-and-execute-nuxt-app-plugins) ### 6. 路由验证 - 如果在 `definePageMeta` 中定义了 `validate` 方法,则调用该方法验证动态路由参数 - 如果验证失败,可能会终止请求或重定向 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-4-route-validation) ### 7. 执行 Nuxt 应用中间件 - 执行全局路由中间件、命名路由中间件和匿名路由中间件 - 中间件可以执行重定向,这会导致浏览器收到 `Location:` 头并发起新请求 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-5-execute-nuxt-app-middleware) ### 8. 页面和组件设置 - 初始化页面和组件 - 使用 `useFetch` 和 `useAsyncData` 获取所需数据 - 服务器端不执行 Vue 生命周期钩子如 `onBeforeMount`、`onMounted` 等 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-6-setup-page-and-components) ### 9. 渲染和生成 HTML 输出 - 将组件与 `unhead` 设置结合生成完整的 HTML 文档 - 调用 `app:rendered` 钩子 - 调用 `render:html` 钩子,允许操作生成的 HTML - 将 HTML 和相关数据发送回客户端 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-7-render-and-generate-html-output) ## 客户端处理 ### 1. 执行 Nuxt 应用中间件 - 中间件在服务器端和客户端都会运行 - 可以使用 `import.meta.client` 和 `import.meta.server` 区分环境 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-3-execute-nuxt-app-middleware) ### 2. 挂载 Vue 应用和水合 - 调用 `app:beforeMount` 钩子 - 调用 `app.mount('#__nuxt')` 将 Vue 应用挂载到 DOM - Vue 执行水合步骤,使客户端应用程序具有交互性 - 调用 `app:mounted` 钩子 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-4-mount-vue-application-and-hydration) ### 3. Vue 生命周期 - 浏览器执行完整的 Vue 生命周期 - 包括 `onBeforeMount`、`onMounted` 等钩子 [Nuxt 生命周期](https://nuxt.com/docs/guide/concepts/nuxt-lifecycle#step-5-vue-lifecycle) ## 重要说明 - 服务器端重定向会导致浏览器收到 `Location:` 头并发起新请求,所有应用状态将重置 - 中间件在服务器端渲染和客户端水合期间都会执行,可能导致代码执行两次 - 对于 API 请求,建议使用 `useAsyncData`、`useFetch` 等 SSR 友好的组合式函数,确保服务器端获取的数据在水合期间被重用 [通用渲染](https://nuxt.com/docs/guide/concepts/rendering#universal-rendering)