You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Next.js动态页面设置基于请求时间的Expires头

解决Next.js中基于请求时间生成Expires缓存头的问题

你之前在next.config.js中设置的headers()函数只会在Next.js服务器启动时执行一次,所以Date.now()取的是服务器启动时刻的时间,导致所有请求的Expires头都是固定值,无法跟随请求时间动态变化。下面提供两种可行的解决方案:

方案一:使用Next.js Middleware(全局生效,推荐)

Next.js 12及以上版本支持Middleware,它会在每个请求到达时触发,正好可以用来动态计算请求时间对应的Expires头。

  1. 在项目根目录创建middleware.ts(或.js)文件
  2. 写入以下代码:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 06:14:57