我一直在为此绞尽脑汁。我正在使用 NextJS 13 的新应用程序路由器。我尝试通过 middleware.ts 设置响应 Cache-Control 标头,但它没有改变。我也在 next.config.js 中尝试过,但这也不起作用。我设置自定义标头没有问题,但 NextJS 总是自动将 Cache-Control 设置为“无存储,必须重新验证”。我缺少什么?如何更改此标题?
带有 App Router 的 NextJS 自动处理缓存控制标头。如果您尝试将其设置为
next.config.js
它将在生产中被内置缓存机制覆盖
在开发模式下
npm run dev
缓存是no-store, must-revalidate
。
在生产中,NextJS 13 使用 SWR 策略 (
s-maxage=31536000, stale-while-revalidate
)。只有数据获取和动态生成页面内容的缓存失效机制。
最初静态渲染的页面目前没有机制可以在 Vercel 托管生态系统之外的初始加载时强制最终用户进行新的获取,该生态系统负责处理此问题。
如果不需要服务端渲染,我建议不要使用Next,而使用Vite。如果您确实需要服务器端渲染并且不想在 Vercel 上托管,我建议您使用一个适合 Vercel 生态系统的黑盒框架(例如 Remix)。
我不确定它是否能解决您的问题,但我可能会帮助其他人,我花了几乎几天的时间试图找到那篇文档。
如前所述,您无法重写
Cache-control
标头,NextJS 将始终覆盖它们(除非您在服务器级别创建中间件)。
但是,对于静态页面,例如
/posts
,您可以添加页面段配置revalidate。这需要几秒钟的时间,然后这将是 Cache-control
标题中的数字。
如果你像我一样处理动态页面,
post/[id]
,NextJS 建议使用fetch
或其他可缓存的获取并将数据缓存在服务器上,但即使大陆是静态。
您可以选择再次使用段配置,dynamic,您可以使用它来强制静态页面为动态页面,或将动态页面行为为静态页面。
因此,如果您将此代码添加到动态页面中:
export const dynamic = 'force-static';
export const revalidate = 60;
您的标题将如下所示:
Cache-control: s-maxage=60, stale-while-revalidate
这样,您就可以使用
Cache-control
标题强制动态页面变为静态,但我建议始终使用 revalidate
选项,以便您的页面得到更新。
我仍在研究通过将页面转换为静态来重新验证的可能性,所以如果有人可以为这种方法添加更多提示/警告,我会很高兴。