配置一套稳健的 Cloudflare CDN 缓存策略,是 2026 年为企业级网站进行速度优化时影响最大的工程任务之一。许多 Web 平台之所以延迟很高,是因为每一个用户请求都必须访问源站数据库服务器才能渲染页面。这种对源站的依赖会拖慢 First Contentful Paint(FCP)和 Largest Contentful Paint(LCP)等速度指标,而将静态页面布局与资源组件存储在全球各地的边缘节点,则能从最近的边缘节点提供快速、低延迟的响应。本指南将详细拆解缓存机制、Edge Cache TTL 规则以及动态 cookie 绕过配置。
[!TIP] 缓存优化提示: 避免缓存包含已登录用户信息的 HTML 页面。请始终配置 Cache Rules,使其在请求头中检测到特定会话 cookie(例如 WordPress cookie 或自定义认证令牌)时绕过边缘缓存。
关键要点:
- Cloudflare CDN 缓存减少了后端服务器的数据库查询,从而降低托管成本。
- Cache Rules 允许开发者根据内容类型和目录设置自定义 TTL 值。
- 部署 Cache Everything 规则需要配置会话 cookie 绕过,以防止用户数据泄露。
- 直接从边缘节点提供静态页面有助于网站在移动设备上通过 Core Web Vitals。
缓存配置:Page Rules 与 Cache Rules
要充分发挥交付管线的效能,您必须选择合适的仪表盘控制模型。根据 Cloudflare Developer Docs 的缓存指南,旧版的 Page Rules 正被模块化的 Cache Rules 取代。因此,开发者应实施以下配置:
默认情况下,CDN 网络只缓存媒体格式、样式表和脚本。因此,您必须配置三个核心资源选项:
- HTML 缓存: 要实现即时页面加载,您必须指示 CDN 缓存 HTML 文档结构。因此,这会停止数据库查询。
- Cache-Control 头: 配置您的 Symfony 或 PHP 后端服务器发送自定义的
s-maxage指令,以指示边缘服务器存储页面的时长。此外,这还支持自定义 TTL 规则。 - Browser Cache TTL: 设置更短的浏览器缓存生命周期(例如 4 小时),以确保您修改站点布局时用户能收到更新。因此,这可以防止布局不匹配的问题。
对于交互式 Web 门户,您无法一概而论地缓存所有页面。因此,您必须建立两条动态绕过规则:
- 会话绕过: 构建规则,指示 CDN 在请求携带认证或会话 cookie 时绕过缓存,从而让已登录用户始终收到个性化的响应,而匿名访客仍由边缘缓存提供服务。
- 查询字符串排序: 配置边缘数据库缓存,使其在评估缓存键时忽略次要的分析变量(例如 UTM 标签)。因此,这可以防止缓存碎片化。
要安全地部署企业级边缘缓存策略,请完成这一技术验证流程。采用以下四个优化步骤:
- 审计 HTTP 头: 验证您的源站服务器发送干净的
Cache-Control和Vary头,且不带认证阻断。 - 起草模块化 Cache Rules: 配置目标 Cache Rules,将静态分类目录存储长达 30 天。
- 构建认证例外: 创建在检测到登录 cookie 时绕过边缘缓存的规则。
- 部署 Purge API Webhook: 配置数据库保存操作,使其在您更新页面时触发自动化的 Purge API 请求。
性能对比:边缘缓存与源站获取
为了说明速度上的收益,下表详细列出了实际的加载指标:
| 性能指标 | 源站服务器获取(无 CDN 缓存) | 边缘缓存命中(CDN 启用) | 预期速度提升 |
|---|---|---|---|
| Time to First Byte (TTFB) | 450 - 800 毫秒 | 15 - 35 毫秒 | 初始服务器响应最多快 95% |
| 移动端 LCP(最大图像) | 3.8 秒(差) | 1.4 秒(好) | 干净地通过 Core Web Vitals 指标 |
| 源站 CPU 负载 | 高(每个页面都查询数据库) | 极低(边缘处理 90% 的命中) | 降低托管成本并提升稳定性 |
前提条件
在您接触仪表盘之前,请确保已准备好以下内容:
- 一个已通过 Cloudflare 代理的域名(橙色云朵 DNS 设置,而非灰色/仅 DNS)。
- 对您源站配置的访问权限——Nginx、Apache 或应用层——以便您可以设置响应头。
- 如果您打算自动化清除缓存,需要一个范围限定为 Zone → Cache Purge 的 API 令牌。在 My Profile → API Tokens 下创建它。
- 一种检查原始 HTTP 头的方法:命令行上的
curl,或 Chrome DevTools 中的 Network 标签。 - 一个 staging URL 或一条低流量路径,以便在向全站推出任何内容之前进行试验。
Free 或 Pro 套餐足以完成下面的每一个步骤。Cache Rules 在所有套餐上都可用,尽管少数缓存键选项和 Tiered Cache 需要更高的套餐等级。
步骤 1:从源站发送正确的 Cache-Control 头
只有当您的源站没有主动禁止时,Cloudflare 才会将响应视为可缓存。HTML 从不被缓存的最常见原因,就是源站在每个请求上返回 Set-Cookie 头或一个限制性的 Cache-Control。
在源站设置明确的指令。在 Nginx 中:
1location ~* \.(css|js|woff2|jpg|png|webp|svg)$ {
2 add_header Cache-Control "public, max-age=31536000, immutable";
3}
4
5location / {
6 # HTML: short browser life, long shared (edge) life
7 add_header Cache-Control "public, max-age=0, s-maxage=86400";
8}
s-maxage 指令针对的是像 Cloudflare 边缘这样的共享缓存,而 max-age=0 则让访客的浏览器持续重新验证,从而使他们在一次部署后绝不会看到过期的 HTML。带指纹的资源上的 immutable 令牌会告诉浏览器完全不必重新验证它们。
对于由应用驱动的响应(PHP 或 Symfony),请在代码中表达相同的意图:
1$response->setPublic();
2$response->setMaxAge(0); // browser
3$response->setSharedMaxAge(86400); // edge / s-maxage
经过认证或个性化的响应必须明确地选择退出,否则一条过于宽泛的规则可能会把一个用户的页面提供给另一个用户:
1Cache-Control: private, no-store
步骤 2:用 Cache Rule 使 HTML 可被缓存
默认情况下,Cloudflare 将 HTML 标记为 DYNAMIC 并且从不存储它。要改变这一点,请在 Caching → Cache Rules → Create rule 下创建一条规则。
编写一个表达式,匹配您想要缓存的页面,同时排除任何动态内容:
1(http.host eq "example.com"
2 and not starts_with(http.request.uri.path, "/wp-admin")
3 and not starts_with(http.request.uri.path, "/cart")
4 and not starts_with(http.request.uri.path, "/checkout")
5 and not starts_with(http.request.uri.path, "/my-account"))
然后设置规则动作:
- Cache eligibility: Eligible for cache——旧版“Cache Everything”行为的现代等价物。
- Edge TTL: Use cache-control header if present,以便您在步骤 1 中设置的
s-maxage生效;如果该头缺失,则回退到一个固定值,例如 1 天。 - Browser TTL: Respect origin。
步骤 3:添加 Cookie 绕过,使已登录用户永远不被缓存
这是大多数指南跳过的步骤,也是它们跳过时会泄露数据的步骤。添加第二条规则,放在资格规则之上,使其在存在真正的会话 cookie 时强制绕过。Cloudflare 自上而下评估 Cache Rules,因此对于已认证的访客,较早的绕过规则总是胜出。
1http.cookie contains "wordpress_logged_in_"
2or http.cookie contains "wp-postpass_"
3or http.cookie contains "woocommerce_items_in_cart"
4or http.cookie contains "comment_author_"
将动作设置为 Bypass cache。对于非 WordPress 技术栈,请将 cookie 名称替换为您框架的会话标识符——PHPSESSID、laravel_session、connect.sid 等等。请严格限定其范围:在这里匹配像 _ga 这样宽泛的分析 cookie,会意外地为每一位匿名访客也绕过缓存。
步骤 4:规范化缓存键
仅因一个跟踪参数而不同的两个 URL 应当共享同一个缓存对象。在资格规则内,打开 Cache Key → Query String,选择 Ignore specific query string parameters,并列出分析键:
1utm_source, utm_medium, utm_campaign, utm_term, utm_content, fbclid, gclid
这会将 /pricing?utm_source=newsletter 和 /pricing?gclid=123 合并到单一的缓存条目上,从而提升您的命中率,而不是将其碎片化到数千个几乎重复的键上。
如何验证缓存 HIT 或 MISS
永远不要假设一条规则有效——要去测量它。Cloudflare 提供的每个响应都带有一个 cf-cache-status 头。请求同一个 URL 两次,观察它的变化:
1curl -sI https://example.com/ | grep -i cf-cache-status
2# First request: cf-cache-status: MISS
3# Second request: cf-cache-status: HIT
您会遇到的值以及各自的含义:
cf-cache-status | 含义 | 应对措施 |
|---|---|---|
| HIT | 直接从边缘提供 | 按预期工作 |
| MISS | 尚未缓存;从源站获取并现已存储 | 重新请求以确认它变为 HIT |
| DYNAMIC | Cloudflare 判定其不可缓存 | 规则未匹配,或源站禁止缓存 |
| BYPASS | 某条规则或 cookie 绕过跳过了缓存 | 在已登录请求上属预期 |
| EXPIRED | TTL 已过,已与源站重新验证 | 正常;若发生过于频繁,请提高 Edge TTL |
| REVALIDATED | 已过期,经 ETag 确认仍然新鲜 | 正常 |
如果您始终只看到 DYNAMIC,说明资格规则未被触发。请确认表达式中的主机名,然后检查源站没有在 HTML 文档上发送 Cache-Control: private 或 Set-Cookie。
常见陷阱与故障排查
- 每个响应上的
Set-Cookie。 Cloudflare 不会缓存设置了 cookie 的响应。分析插件、CSRF 令牌和 A/B 测试工具经常会给 HTML 文档附加一个。请将该逻辑移到异步请求中,或在可缓存路径上剥离该头。 - 匿名访客上的
BYPASS。 几乎总是由于 cookie 绕过规则过于宽泛——一个像_ga这样的通用 cookie 匹配了您的表达式。请将绕过限制为仅针对真正的会话 cookie。 - 部署后的过期页面。 Edge TTL 正在履行其职责;您只是忘记了清除缓存。请在发布时触发一次有针对性的清除,而不是把 TTL 缩短到几秒钟。
- Vary 头被忽略。 Cloudflare 只按
Accept-Encoding来变化其缓存;它不会为任意的Vary: User-Agent或Vary: Cookie保留单独的副本。请通过响应式 CSS 或一个 Worker 来提供针对设备的标记,而不是依赖 Vary。 - Development Mode 一直开着。 它会绕过缓存三个小时,并悄悄地使每个响应看起来不可缓存。在测试之前请确认它已关闭。
生产环境考量与自动化清除
一旦单条路径表现正确,就在低流量时段将规则扩展到整个站点,并在 Caching → Overview 中观察您的命中率——一个健康的静态站点会稳稳地保持在 90% 以上。
将您的 CMS 接通,使其只清除发生变化的内容,而非整个 zone。按 URL 进行的有针对性清除能让相邻页面在缓存中保持温热:
1curl -X POST \
2 "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache" \
3 -H "Authorization: Bearer ${CF_API_TOKEN}" \
4 -H "Content-Type: application/json" \
5 --data '{"files":["https://example.com/pricing"]}'
从您的发布钩子中调用它,这样编辑者的更新会在几秒钟内上线,而其他一切都保持缓存。对于大型目录,将相关的 URL 归入一个 Cache Tag(Enterprise)之下,或按前缀清除,并启用 Tiered Cache,通过在未命中到达您的源站之前将其路由经过一个区域父节点,来提升全局命中率。
与一家经过审核的英国 Cloudflare 咨询公司合作
正确地做出这些缓存决策可以保护您的源站服务器,并为每一位访客加速页面交付。Mecanik 提供专业的技术 SEO 审计 服务,并通过我们的网站开发 页面提供基础设施扩展。我们专注于 Symfony 边缘集成、自定义 Cloudflare Cache Rules 以及边缘原生部署。今天就联系我们,安排您的技术范围界定研讨会。
常见问题(FAQ)
什么是 cloudflare cdn 缓存? Cloudflare cdn 缓存是将您网站的页面、图像和脚本文件的静态副本存储在遍布世界各地的边缘服务器上的过程。这种配置允许用户请求由最近的物理服务器来提供,从而减少网站的加载时间。
如何在不泄露用户数据的情况下缓存 HTML 页面? 要安全地缓存 HTML,请配置一条带有“Bypass Cache”动作的 Cache Rule,使其在请求头中存在会话或管理员 cookie 时触发。这一设置可确保已登录的门户用户始终从源站数据库获取动态内容。
Edge TTL 和 Browser TTL 有什么区别? Edge TTL(Time-To-Live)规定 Cloudflare CDN 服务器在向您的源站服务器请求新副本之前,将您的内容存储多长时间。相反,Browser TTL 决定访客的本地浏览器缓存保留文件的时长。
为什么查询字符串缓存会影响网站性能? 如果查询字符串(例如 UTM 跟踪标签)未被规范化,CDN 会将每个变体视为唯一的 URL,从而向您的源站服务器生成重复请求。配置缓存键规范化可以防止这种抓取重复。
边缘缓存能改善我的 Core Web Vitals 分数吗? 可以,直接从边缘服务器提供您的 HTML 和媒体资源,能够最小化 Time-to-First-Byte(TTFB)和 Largest Contentful Paint(LCP)的时间。因此,这一缓存策略直接改善您的移动端页面速度排名。
评论