---
id: ssr-query-streaming
track: learn
product: query
locale: zh-CN
order: 16
revision: 1
sourceCheckedOn: "2026-08-03"
versionRange: "Router ^1 / Query ^5"
verifiedAgainst: "@tanstack/react-router@1.170.18 + @tanstack/react-router-ssr-query@1.167.1 + @tanstack/react-query@5.101.4"
contentModel: 2
prerequisites:
  - "完成 Loader + Query 缓存课程"
  - "应用启用 TanStack Router SSR 或 TanStack Start"
sourceRefs:
  - "https://tanstack.com/router/latest/docs/integrations/query"
  - "https://tanstack.com/query/latest/docs/framework/react/guides/ssr"
---

# 在请求之间隔离并流式恢复 Query

> 用 Router SSR Query 集成自动完成脱水、恢复和流式传输，并为每个服务端请求创建独立缓存。

**Outcome:** 能选择阻塞或流式查询，避免跨用户缓存泄漏，并验证 hydration 后不会立刻重复请求。

## 每个请求一份 QueryClient

服务端模块级 QueryClient 会让不同请求甚至不同用户共享缓存。把 QueryClient 创建在 getRouter 内，并将同一实例同时传入 Router Context 和 setupRouterSsrQueryIntegration；集成负责初始脱水、客户端恢复和后续 Query 结果流。

File: `src/router.tsx`

```tsx
import { QueryClient } from '@tanstack/react-query'
import { createRouter } from '@tanstack/react-router'
import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query'

export function getRouter() {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { staleTime: 30_000 } },
  })
  const router = createRouter({
    routeTree,
    context: { queryClient },
  })

  setupRouterSsrQueryIntegration({ router, queryClient })
  return router
}
```

## 明确什么阻塞，什么流式到达

Loader return 或 await ensureQueryData 会把关键数据放在进入路由之前；启动 fetchQuery 但不 await 可以让结果在初始渲染期间继续流到客户端。useSuspenseQuery 会参与服务端渲染与流式恢复，普通 useQuery 则在 hydration 后从客户端发起。先按页面价值选择，而不是把所有请求都阻塞。

## SSR 载荷是公开给浏览器的

脱水后的缓存会进入 HTML 或流式响应，不能包含未经授权的数据、秘密或只应停留在服务端的字段。自定义序列化必须正确转义 HTML 上下文；应优先复用框架集成，而不是直接 JSON.stringify 后拼进 script。

> **Note:** 给 SSR 查询设置大于 0 的 staleTime，避免刚恢复就因为默认陈旧而立即重新请求。

## 实践与验证

### 完成检查点

每个 SSR 请求创建独立 QueryClient，关键查询可恢复，非关键查询可流式到达，并且 hydration 后不立即重复请求。

### 动手练习

让 Issue 摘要阻塞首屏、活动记录流式返回，并用两个并发会话证明缓存数据不会串用户。

### 验证方法

检查服务器请求日志、HTML/流式响应与浏览器网络面板；首屏只有预期请求，序列化载荷不含私密字段，两个用户看到各自数据。

### 常见错误

- 在服务端模块顶层复用全局 QueryClient。
- 把秘密或未经授权的字段脱水到浏览器可见载荷。

## Official sources

- https://tanstack.com/router/latest/docs/integrations/query
- https://tanstack.com/query/latest/docs/framework/react/guides/ssr
