Next.js中fetch配置force-cache后为何缓存未生效?
Next.js服务端组件fetch缓存未生效的原因及解决方法
在Next.js服务端组件中,使用fetch并设置cache: 'force-cache'后,三次调用同一接口却得到递增的计数结果,缓存未按预期生效:
export default async function Home() { async function fetch_visits() { return ( await ( await fetch( 'https://webcodingcenternextjs9lrayfq-mqjz--3000--60a75bde.local-credentialless.webcontainer.io/data', { cache: 'force-cache' } ) ).json() ).visits; } return ( <> <p>Count: {await fetch_visits()}</p> <p>Count: {await fetch_visits()}</p> <p>Count: {await fetch_visits()}</p> </> ); }
核心原因
- 服务器响应头限制缓存:Next.js的
fetch缓存策略会被服务器返回的Cache-Control响应头覆盖。如果你的/data接口返回的响应头包含no-store、no-cache或max-age=0,即使设置了force-cache,Next.js也不会缓存该响应,每次调用fetch都会发起新请求,导致计数递增。 - 函数封装导致请求去重失效:虽然Next.js默认会在同一次服务端渲染周期内自动去重重复的
fetch请求,但将fetch封装在内部函数中时,可能因请求标识未被框架正确识别,导致重复发起请求。
解决方法
方法1:手动缓存请求结果(最直接)
在组件内部仅发起一次请求,将结果缓存后复用,避免重复调用fetch:
export default async function Home() { // 仅发起一次请求并缓存结果 const visits = (await (await fetch( 'https://webcodingcenternextjs9lrayfq-mqjz--3000--60a75bde.local-credentialless.webcontainer.io/data', { cache: 'force-cache' } )).json()).visits; return ( <> <p>Count: {visits}</p> <p>Count: {visits}</p> <p>Count: {visits}</p> </> ); }
如果需要保留函数封装,可在函数内部添加本地缓存逻辑:
export default async function Home() { let cachedVisits: number | undefined; async function fetch_visits() { if (!cachedVisits) { cachedVisits = (await (await fetch( 'https://webcodingcenternextjs9lrayfq-mqjz--3000--60a75bde.local-credentialless.webcontainer.io/data', { cache: 'force-cache' } )).json()).visits; } return cachedVisits; } return ( <> <p>Count: {await fetch_visits()}</p> <p>Count: {await fetch_visits()}</p> <p>Count: {await fetch_visits()}</p> </> ); }
方法2:修改服务器响应头(若有权限)
如果可以控制/data接口的服务端代码,设置允许缓存的Cache-Control响应头,例如:
// Node.js/Express示例:设置服务器缓存60秒 res.setHeader('Cache-Control', 's-maxage=60');
这样Next.js会遵循响应头的缓存规则,自动缓存请求结果,避免重复发起请求。
内容的提问来源于stack exchange,提问作者Chong Lip Phang
相关产品推荐
相关产品推荐

