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