HTTP 缓存、协商与发布失效

验证:未记录
适用版本
未记录
验证范围
尚未登记验证记录。

HTTP(Hypertext Transfer Protocol,超文本传输协议)缓存有浏览器私有缓存和代理/CDN(Content Delivery Network,内容分发网络)共享缓存。是否存、存多久、如何区分内容、更新后怎样失效是四个独立问题。

1. 一次读取的决策#

查缓存键 → 没有副本 → 请求源站 → 按策略保存
         → 有副本且新鲜 → 直接复用
         → 过期/要求验证 → If-None-Match → 304:复用正文
                                          → 200:替换正文

ETag 是表示版本的校验标识,不保证一定是文件哈希。no-cache 允许存但复用前需验证;no-store 不允许存本次内容;private 禁止共享缓存存储。s-maxage 面向共享缓存,max-age 控制一般新鲜期。HTTP 缓存标准。

2. Hands-on:实测 200 → 304 → 更新后 200#

先启动 隔离实验环境,同一 Bash 会话保留 $HTTP_LAB_DIR:

curl -sS -D "$HTTP_LAB_DIR/first.headers" -o "$HTTP_LAB_DIR/first.body" http://127.0.0.1:18080/asset.txt
ETAG=$(awk 'tolower($1)=="etag:" {sub(/^[^:]*:[ \t]*/, ""); sub(/\r$/, ""); print; exit}' "$HTTP_LAB_DIR/first.headers")
test -n "$ETAG"
curl -sS -D - -o /dev/null -H "If-None-Match: $ETAG" http://127.0.0.1:18080/asset.txt
printf 'release-two-with-different-size\n' > "$HTTP_LAB_DIR/www/asset.txt"
sleep 1 # 给 Docker Desktop 绑定目录同步留出时间
curl -sS -D - -H "If-None-Match: $ETAG" http://127.0.0.1:18080/asset.txt

预期依次 200、304、200,最后返回新内容与新 ETag。curl 不像浏览器一样自动维护内容缓存,这里显式发送条件头来观察协议。修改文件长度避免静态服务器依赖时间戳/长度生成的 ETag 在快速实验中不变。

3. 在真实 CDN 验收缓存键#

  1. 选择公开、可回收的测试对象,响应明确设置短 TTL(Time To Live,存活时间),记录发布版本。
  2. 对同一 URL 连续 GET,比较正文、Age、ETag 和供应商缓存命中头;没有 Age 不能单独证明未缓存。
  3. 若语言、国家、编码或 query 会改变内容,成对请求不同值,确认返回与缓存键一致。只转发请求头,不代表已纳入缓存键。
  4. 登录态/租户数据使用明确禁共享缓存策略;不能假定存在 Cookie 就自动绕过 CDN。
  5. 发布新版本后验证旧/新页面引用、304、压缩版本和错误响应缓存,最后执行受控失效或等待到期。

对应可部署案例见 CloudFront 缓存分区与验收。

4. 发布策略与回退#

对象 推荐策略
内容哈希命名的静态文件 长缓存 + immutable,更新时换 URL;保留旧文件覆盖回退窗口
HTML/版本清单 短缓存或强制协商,避免指向已删除资源
敏感业务接口 no-store,并核对 CDN 缓存规则,不能只改应用头
动态按 Origin 返回的跨域许可 Vary: Origin,并核对实际边缘缓存键

回退同时考虑源站、CDN、浏览器和 Service Worker。删除源站对象不等于删除边缘副本;只把新响应改成 no-store 不会清空旧缓存。恢复实验文件用 printf 'release-one\n' > "$HTTP_LAB_DIR/www/asset.txt",再按首页清理。

搜索文档

输入关键词,搜索所有文档。

↑ ↓ 选择 · Enter 打开 · Esc 关闭