商品列表按价格排序后却显示成默认顺序,或个人页面被错误地展示给另一位访客,常见原因不是页面内容本身,而是缓存规则没有区分请求。设置网页缓存规则设置:缓存时长、查询参数与Cookie时,应先判断响应能否复用,再决定缓存多久、哪些请求要分开处理。
缓存策略通常由三部分组成:响应的新鲜时间、缓存键包含哪些请求信息,以及哪些内容禁止被共享缓存保存。三者需要一起设计;只缩短缓存时长,并不能修复错误的缓存键。
先按内容变化速度决定缓存时长
缓存时长,也就是 TTL,表示缓存内容可直接复用的时间。常见响应头包括 Cache-Control 的 max-age 和面向共享缓存的 s-maxage。实际支持情况取决于浏览器、反向代理或其他缓存层的配置,不能只看源站响应头就假定所有层行为一致。
- 公开且较少变化的页面:可从几分钟到数小时评估,例如不含个人信息的说明页。更新较频繁时应采用较短时间,并确认内容发布后如何让旧缓存失效。
- 频繁变化的列表或状态:可先用几十秒到几分钟作为测试范围,再按更新频率和可接受的陈旧时间调整。库存、价格等信息若要求及时,应缩短 TTL 或不缓存相关响应。
- 个人信息或账户操作响应:通常应设置 private 或 no-store,避免进入共享缓存。no-cache 的含义是使用前需要重新验证,并不等同于禁止存储。
这些范围只是配置起点,不是通用标准。页面更新方式、缓存层级和业务对旧内容的容忍度都会影响选择。若缓存期间源站内容可能变化,还应确认是否有主动清除或版本更新机制。
查询参数:逐项判断是否影响内容
查询参数缓存键决定不同参数值是否被当作不同请求。以 /catalog?sort=price 为例,sort 会改变排序,理应参与缓存键;若把它忽略,用户可能收到不符合请求的结果。相反,纯统计用途的参数在确认不影响页面输出后,才适合从缓存键中排除。
建立参数规则的可执行步骤
- 列出页面会读取的参数,并标记其作用:筛选、分页、排序、语言,还是仅用于统计。
- 让会改变响应内容的参数参与缓存键;确认不影响内容的追踪参数,才考虑忽略或统一处理。
- 检查参数缺省值、重复参数和编码形式。例如 page=1 与未传 page 是否确实返回相同内容,不能仅凭名称推断。
- 用不同参数请求同一路径,比较状态码、响应内容及缓存命中情况;也检查参数顺序变化是否导致不必要的重复缓存。
忽略参数能减少缓存条目,但规则过宽会造成内容串用;完整保留所有参数较安全,却可能让大量只差统计参数的请求各占一个缓存项。应按实际响应行为取舍,并在规则变更后验证缓存键。
Cookie:个性化响应不要混入公共缓存
Cookie 常用于登录状态、购物车、语言偏好或实验分组。若响应会根据这些值变化,共享缓存就不能把所有请求当成同一页面。直接把全部 Cookie 纳入缓存键可能使键的组合数量显著增加,也未必能避免敏感信息风险。
更稳妥的做法是先判断响应是否真的依赖 Cookie:与登录无关的公开页面,可以在确认内容一致后按公共页面缓存;依赖账户身份、购物车或私人数据的响应,应使用 private 或 no-store,或明确绕过共享缓存。Vary: Cookie 可以表达响应因 Cookie 不同而变化,但可能导致命中率下降,且要确认缓存层遵循该响应头。仅看到 Set-Cookie 响应头,也不能代替对具体缓存产品规则的核验。
上线前的检查清单
- 为页面分类:公开静态、公开动态、个性化或敏感响应。
- 分别设定 TTL 与 Cache-Control 指令,明确浏览器缓存和共享缓存的预期行为。
- 核对缓存键是否包含影响内容的查询参数,并确认 Cookie 处理方式。
- 用匿名请求、登录请求及不同参数请求做对照,检查响应内容和缓存状态。
- 确认内容更新后的失效路径;如无法及时清除旧内容,就降低 TTL 或避免缓存高风险响应。
好的网页缓存规则设置:缓存时长、查询参数与Cookie不是追求最高命中率,而是在复用效率与内容正确、隐私安全之间划清边界。先识别响应差异,再确定 TTL、缓存键和 Cookie 策略,通常比事后排查误缓存更可靠。
常见问题
缓存时间越长越好吗?
不一定。长 TTL 能减少回源,但内容更新后旧版本可能保留更久;应结合更新频率和可接受的陈旧时间设置。
所有查询参数都要加入缓存键吗?
不必。只要参数会改变响应,就应区分;确认纯统计参数不影响内容后,才考虑忽略。
有 Cookie 的请求一定不能缓存吗?
不一定。关键是响应是否依赖 Cookie,以及缓存是否共享。个性化或敏感响应应避免进入公共缓存;公开且不受 Cookie 影响的内容可按实际规则处理。