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

如何缓存含getServerSideProps的Next.js动态渲染页面?

解决方案:基于用户状态的SSR页面缓存优化

针对你的需求,推荐结合Next.js 请求头自定义 + CDN 缓存规则的方案,既保留SSR的用户体验,又能让Cloudflare根据用户登录状态缓存不同渲染版本,无需修改路由或放弃SSR。

核心思路

通过中间件(Middleware)提前识别用户登录状态,为请求添加自定义标识头;再在getServerSideProps中根据这个标识获取状态,同时设置合理的缓存头和Vary字段,让CDN(Cloudflare)基于用户状态缓存对应的渲染结果。

步骤1:添加Middleware处理用户状态

在项目根目录创建middleware.ts,提前解析用户登录状态并添加自定义请求头:

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  // 从Cookie/请求上下文获取用户ID,逻辑和你现有getUserIdOrNull一致
  const userId = getUserIdOrNullFromCookie(request.cookies);
  // 简化为两种状态:登录/未登录
  const userStatus = userId ? "logged-in" : "anonymous";

  // 给后续请求添加自定义标识头
  const modifiedHeaders = new Headers(request.headers);
  modifiedHeaders.set("X-User-Status", userStatus);

  return NextResponse.next({
    request: { headers: modifiedHeaders }
  });
}

// 仅匹配需要缓存的/stuff页面
export const config = {
  matcher: "/stuff"
};

步骤2:修改getServerSideProps设置缓存规则

更新pages/stuff.ts中的getServerSideProps,读取自定义头并设置CDN缓存策略:

export function getServerSideProps(context) {
  // 从自定义头获取用户状态
  const userStatus = context.req.headers["x-user-status"] as string;
  const isLoggedIn = userStatus === "logged-in";

  // 设置缓存规则:允许CDN缓存(public),缓存1小时,过期时返回旧内容并后台更新
  context.res.setHeader(
    "Cache-Control",
    "public, s-maxage=3600, stale-while-revalidate=86400"
  );
  // 告诉CDN根据自定义头区分缓存版本
  context.res.setHeader("Vary", "X-User-Status");

  return {
    props: { somethingComplicated: getSomethingComplicated(isLoggedIn) }
  };
}

export default function Home({ somethingComplicated }) {
  return <div>{somethingComplicated}</div>;
}

方案优势

  • 保留SSR:页面在服务端渲染完成后再返回,用户体验好;
  • CDN缓存有效:Cloudflare会根据X-User-Status缓存两个版本(登录/未登录),命中率高;
  • 无需修改路由:用户访问的URL始终是/stuff,没有复杂的重定向逻辑;
  • 性能兼顾:stale-while-revalidate保证缓存过期时,用户仍能快速获取旧内容,后台异步更新缓存。

注意事项

  • 确保Cloudflare支持缓存带Vary头的响应(默认支持,若有异常可检查缓存规则);
  • 如果getSomethingComplicated的结果随用户个体差异(而非仅登录状态)变化,可将X-User-Status替换为用户ID的哈希值,但需注意缓存键数量不要过多,避免缓存碎片化;
  • 若直接使用Cookie作为Vary字段,需确保Cookie中仅包含必要的登录标识,避免因Cookie内容过多导致缓存键爆炸。

内容的提问来源于stack exchange,提问作者evandwight

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:20:27