如何在 SSR 中处理数据获取?

介绍如何在服务端渲染(SSR)中处理数据获取,包括策略、实现细节和优化措施。通过具体框架示例说明数据获取的实现方式以及错误处理。

服务端渲染 中等 数据获取 SSR 服务器端

在服务器端渲染(SSR)中处理数据获取涉及在服务器运行期间预先获取必要数据,确保渲染生成的 HTML 包含动态内容,从而提升首次加载性能和 SEO。以下是核心策略和实现细节:

  1. 定义服务端专用数据获取函数:SSR 框架通常提供特定钩子函数,在路由匹配后运行这些函数获取数据,再将数据注入组件渲染流程。
    • 例如,在 Next.js 使用 getServerSideProps
      // page.tsx
      export async function getServerSideProps(context) {
        const data = await fetch('https://api.example.com/data');
        return { props: { data } }; // 返回数据,作为组件 props
      }
           
      function Page({ data }) {
        return <div>{JSON.stringify(data)}</div>;
      }
           
      export default Page;
      

      该函数运行在服务器端,通过 context 对象可访问请求信息(如 URL、headers),确保数据传输同步完成于组件渲染前。

  2. 基于路由预取数据(Vue 实现):在 Vue 应用中(如 Nuxt),路由初始化时遍历匹配组件,并发请求数据。
    • 核心示例:
      // entry-server.js (Vue SSR)
      export default (context) => {
        return new Promise((resolve, reject) => {
          createApp().then(({ app, router, store }) => {
            router.push(context.url);
            router.onReady(() => {
              const matchedComponents = router.getMatchedComponents();
              if (!matchedComponents.length) reject({ code: 404 });
              // 预取组件数据需求
              Promise.all(matchedComponents.map(component => {
                return component.options.methods.fetchData ? 
                  component.options.methods.fetchData(store) : Promise.resolve();
              })).then(() => {
                resolve(app);
              });
            });
          });
        });
      };
      

      这里使用组件级 fetchData 定义数据逻辑,配合 Vuex(状态管理)集中处理状态传递到客户端。

  3. 数据处理优化和缓存:针对高频请求或敏感数据引入缓存策略:
    • 如 Next.js 在 getServerSideProps 返回头部添加 Cache-Control 配置:
      return { 
        props: { data },
        headers: { 'Cache-Control': 'public, max-age=3600' } 
      };
      
    • 避免数据不一致:在服务端数据接口设计中,确保结果无客户端污染(如避免请求头泄露),并使用类库如 Axios 处理代理:
  4. 错误和边界处理:添加健壮错误捕获逻辑,防止服务器渲染中断:
    async function fetchData() {
      try {
        return await apiCall(); 
      } catch (error) {
        return { error: true };
      }
    }
    

    框架提供机制如 Next.js 的默认错误页面。

通过整合这些策略,SSR 数据获取保障了首屏内容的实时完整性并优化渲染性能。