Next.js文档 - 2.数据获取-SSR

文章目录
  1. 1. getServerSideProps(SSR使用)
    1. 1.1. getServerSideProps何时运行
    2. 1.2. 何时应该使用getServerSideProps
      1. 1.2.1. getServerSideProps 或 API 路由
      2. 1.2.2. getServerSideProps与边缘路由
  2. 2. 在客户端侧获取数据(CSR)
  3. 3. 使用 getServerSideProps 在请求时获取数据
  4. 4. 使用服务端渲染(SSR)进行缓存
  5. 5. getServerSideProps是否会渲染错误页(500)

getServerSideProps(SSR使用)

当你在一个Page中导出了getServerSideProps函数,那么Next将会在每次页面请求前使用getServerSideProps返回的数据进行预渲染。

1
2
3
4
5
export async function getServerSideProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}

请注意,无论渲染类型是什么,任何props都将被传递到页面组件上,并可以在客户端得到的初始HTML中被查看,这是为了让页面能够被正确地水合。请确保你没有将任何不应在客户端上出现的敏感信息传递给props

getServerSideProps何时运行

getServerSideProps仅在服务器端运行,从不在浏览器上运行。如果页面使用getServerSideProps,则:

  • 当你直接请求此页面时,getServerSideProps在请求时运行,并且此页面将使用返回的 props 进行预渲染

  • 当你从客户端侧请求一个从next/linknext/router转变而来的页面时,Next会执行getServerSideProps,向服务器发送一个API请求。

    When you request this page on client-side page transitions through next/link or next/router, Next.js sends an API request to the server, which runs getServerSideProps

getServerSideProps返回用于渲染页面的 JSON。所有这些工作都将由Next自动处理,所以只要你已经声明好了getServerSideProps,那就不需要做任何额外的事情。

您可以使用next-code-elimination来验证 Next.js 从客户端侧产物中删除了什么。

getServerSideProps只能从Page组件(页面文件)导出。您不能从非页面文件中导出它。

请注意,您必须导出getServerSideProps为独立函数——如果您将其添加为页面组件的属性,它将无法工作。

何时应该使用getServerSideProps

getServerSideProps仅当您需要渲染必须在每次请求时预先获取数据的页面时才应使用。这可能是由于请求的数据或属性(如authorization标头或地理位置)决定的。使用getServerSideProps的页面将在请求时在服务器端渲染,并且只有在配置了缓存控制标头时才会被缓存。

如果您不需要在请求页面期间渲染数据,那么您应该考虑在客户端请求数据或使用getStaticProps.

getServerSideProps 或 API 路由

当您想从服务器获取数据时,可能很想去访问API 路由,然后从getServerSideProps调用该 API 路由的逻辑。这是一种不必要且低效的方法,因为它会由于调用getServerSideProps以及访问服务器上运行的 API 路由而导致发出额外的请求。

以下面的例子为例。API 路由用于从 CMS 获取一些数据。然后直接从getServerSideProps调用该 API 路由。这会产生额外的调用,从而降低性能。相反,应该直接将 API 路由中使用的逻辑导入到getServerSideProps。这意味着直接从getServerSideProps内部调用 CMS、数据库或其他 API 。

getServerSideProps与边缘路由

getServerSideProps可以同时与Serverless 和 Edge Runtimes结合使用,你可以在两者中设置 props。但是,目前在 Edge Runtime 中,您无权访问响应对象。这意味着您不能——例如——在getServerSideProps中添加cookie。要访问响应对象,您应该继续使用Node.js 运行时(即默认运行时)。

你可以为通过自定义config来为每个Page显式地设置运行时,例如:

1
2
3
export const config = {
runtime: 'nodejs',
}

在客户端侧获取数据(CSR)

如果你的页面包含频繁更新的数据,并且你不需要预渲染数据,你可以在客户端获取数据。这方面的一个例子是用户特定的数据:

  • 首先,立即显示没有数据的页面。页面的某些部分可以使用静态生成进行预呈现。您可以显示缺失数据的加载状态
  • 首先,立即显示没有数据的页面。页面的某些部分可以使用SSG进行预渲染。您可以显示缺失数据的加载状态
  • 然后,在客户端获取数据并在准备好时显示它

例如,此方法适用于用户仪表板页面。由于仪表板是私有的、特定于用户的页面,因此与 SEO 无关,并且不需要预渲染该页面。数据更新频繁,需要请求时再获取数据。

使用 getServerSideProps 在请求时获取数据

以下示例显示了如何在请求时获取数据并预渲染结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Page({ data }) {
// Render data...
}

// This gets called on every request
export async function getServerSideProps() {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()

// Pass data to the page via props
return { props: { data } }
}

export default Page

使用服务端渲染(SSR)进行缓存

你可以在getServerSideProps内部使用缓存标头(Cache-Control)来缓存动态响应,如:使用stale-while-revalidate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This value is considered fresh for ten seconds (s-maxage=10).
// If a request is repeated within the next 10 seconds, the previously
// cached value will still be fresh. If the request is repeated before 59 seconds,
// the cached value will be stale but still render (stale-while-revalidate=59).
//
// In the background, a revalidation request will be made to populate the cache
// with a fresh value. If you refresh the page, you will see the new value.
export async function getServerSideProps({ req, res }) {
res.setHeader(
'Cache-Control',
'public, s-maxage=10, stale-while-revalidate=59'
)

return {
props: {},
}
}

getServerSideProps是否会渲染错误页(500)

如果getServerSideProps内部抛出错误,它将显示pages/500.js文件。查看500 页的文档以了解有关如何创建它的更多信息。在开发环境下不会使用此文件,而是会显示dev遮罩层。