跳到内容

fetch

Next.js 扩展了 Web fetch() API,允许服务器上的每个请求设置其自己的持久缓存和重新验证语义。

在浏览器中,cache 选项指示 fetch 请求将如何与浏览器的 HTTP 缓存交互。通过此扩展,cache 指示服务器端 fetch 请求将如何与框架的持久性数据缓存交互。

你可以直接在服务器组件中使用 asyncawait 调用 fetch

app/page.tsx
export default async function Page() {
  let data = await fetch('https://api.vercel.app/blog')
  let posts = await data.json()
  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  )
}

fetch(url, options)

由于 Next.js 扩展了 Web fetch() API,你可以使用任何可用的原生选项

options.cache

配置请求应如何与 Next.js 数据缓存交互。

fetch(`https://...`, { cache: 'force-cache' | 'no-store' })
  • auto no cache(默认):Next.js 在开发环境中,每次请求都会从远程服务器获取资源,但在 next build 期间只会获取一次,因为路由将被静态预渲染。如果在路由上检测到动态 API,Next.js 将在每次请求时都获取资源。
  • no-store:Next.js 每次请求都会从远程服务器获取资源,即使在路由上未检测到动态 API 也是如此。
  • force-cache:Next.js 在其数据缓存中查找匹配的请求。
    • 如果存在匹配项且是新鲜的,则将从缓存返回。
    • 如果不存在匹配项或存在过时的匹配项,Next.js 将从远程服务器获取资源,并使用下载的资源更新缓存。

options.next.revalidate

fetch(`https://...`, { next: { revalidate: false | 0 | number } })

设置资源的缓存生命周期(以秒为单位)。

  • false - 无限期缓存资源。语义上等同于 revalidate: Infinity。HTTP 缓存可能会随着时间的推移驱逐较旧的资源。
  • 0 - 阻止资源被缓存。
  • number - (以秒为单位)指定资源应具有最多 n 秒的缓存生命周期。

须知:

  • 如果单个 fetch() 请求设置的 revalidate 数值低于路由的默认 revalidate,则整个路由的重新验证间隔将缩短。
  • 如果同一路由中具有相同 URL 的两个 fetch 请求具有不同的 revalidate 值,则将使用较低的值。
  • 作为一种便利措施,如果将 revalidate 设置为数字,则无需设置 cache 选项。
  • 冲突的选项,例如 { revalidate: 3600, cache: 'no-store' } 将导致错误。

options.next.tags

fetch(`https://...`, { next: { tags: ['collection'] } })

设置资源的缓存标签。然后可以使用revalidateTag按需重新验证数据。自定义标签的最大长度为 256 个字符,最大标签项为 128 个。

故障排除

Fetch 默认 auto no storecache: 'no-store' 在开发环境中未显示最新数据

Next.js 在本地开发中跨热模块替换 (HMR) 缓存服务器组件中的 fetch 响应,以加快响应速度并降低计费 API 调用的成本。

默认情况下,HMR 缓存适用于所有 fetch 请求,包括具有默认 auto no cachecache: 'no-store' 选项的请求。这意味着未缓存的请求在 HMR 刷新之间不会显示最新数据。但是,缓存将在导航或完整页面重新加载时清除。

有关更多信息,请参阅 serverComponentsHmrCache 文档。

版本历史

版本变更
v13.0.0引入 fetch