如何为Next.js动态页面设置基于请求时间的Expires头
解决Next.js中基于请求时间生成Expires缓存头的问题
你之前在next.config.js中设置的headers()函数只会在Next.js服务器启动时执行一次,所以Date.now()取的是服务器启动时刻的时间,导致所有请求的Expires头都是固定值,无法跟随请求时间动态变化。下面提供两种可行的解决方案:
方案一:使用Next.js Middleware(全局生效,推荐)
Next.js 12及以上版本支持Middleware,它会在每个请求到达时触发,正好可以用来动态计算请求时间对应的Expires头。
- 在项目根目录创建
middleware.ts(或.js)文件 - 写入以下代码:
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; // 替换成你的实际缓存时长配置 const CACHE_CONTROL_MAX_AGE_SECONDS = 3600; export function middleware(request: NextRequest) { const response = NextResponse.next(); // 设置Cache-Control头 response.headers.set('Cache-Control', `public, max-age=${CACHE_CONTROL_MAX_AGE_SECONDS}`); // 基于当前请求时间计算Expires头 const expiresTimestamp = Date.now() + CACHE_CONTROL_MAX_AGE_SECONDS * 1000; response.headers.set('Expires', new Date(expiresTimestamp).toUTCString()); return response; } // 匹配所有路由,可根据需求调整(比如只匹配/pages下的路由) export const config = { matcher: '/:path*', };
方案二:在页面/组件中单独设置(针对特定路由)
App Router(Next.js 13+)
在Server Component中直接操作响应头:
import { headers } from 'next/headers'; const CACHE_CONTROL_MAX_AGE_SECONDS = 3600; export default function YourPage() { const responseHeaders = headers(); responseHeaders.set('Cache-Control', `public, max-age=${CACHE_CONTROL_MAX_AGE_SECONDS}`); const expiresDate = new Date(Date.now() + CACHE_CONTROL_MAX_AGE_SECONDS * 1000); responseHeaders.set('Expires', expiresDate.toUTCString()); return <div>页面内容</div>; } // 保持动态渲染,避免Next.js静态缓存 export const dynamic = "force-dynamic";
Pages Router
使用getServerSideProps在请求时动态设置头:
export async function getServerSideProps(context) { const CACHE_CONTROL_MAX_AGE_SECONDS = 3600; // 设置响应头 context.res.setHeader('Cache-Control', `public, max-age=${CACHE_CONTROL_MAX_AGE_SECONDS}`); const expiresDate = new Date(Date.now() + CACHE_CONTROL_MAX_AGE_SECONDS * 1000); context.res.setHeader('Expires', expiresDate.toUTCString()); return { props: {} }; } // 禁用静态生成 export const dynamic = "force-dynamic";
注意事项
- 确保
dynamic = "force-dynamic"已正确设置,避免Next.js自身的静态缓存和Azure CDN缓存产生冲突 Cache-Control的max-age时长和Expires计算的时间要保持一致,否则可能导致CDN缓存策略异常- Middleware方案会对所有匹配的路由生效,适合全局配置;如果只需要给特定路由设置缓存头,调整
matcher规则即可
内容的提问来源于stack exchange,提问作者olivierr91
相关产品推荐
相关产品推荐

