---

title: CDN缓存治理与不可缓存资源策略(Cache-Control/ETag/Immutable)最佳实践

keywords:

  • Cache-Control
  • ETag
  • s-maxage
  • immutable
  • Vary
  • CDN
  • 不可缓存

description: 通过精确的Cache-Control/ETag与Vary策略、不可缓存资源治理与TTL上限控制,实现安全高效的端到端缓存管理。

categories:

  • 文章资讯
  • 技术教程

---

背景与价值

缓存治理影响性能与安全,需对静态资源与动态接口分别治理,确保私有数据不可缓存且公共资源长效稳定命中。

统一规范

  • TTL上限:max-age/s-maxage 不超过 86400(1天)除非版本化静态资源。
  • 不可缓存:用户相关或敏感响应统一 no-store
  • 可缓存静态:版本化资源使用长TTL与 immutable,并提供 ETagVary
  • 统一 nosniff 与内容类型校验。

核心实现

ETag与TTL校验

function b64url(buf: ArrayBuffer): string { const u = new Uint8Array(buf); let s=''; for (let i=0;i<u.length;i++) s+=String.fromCharCode(u[i]); return btoa(s).replace(/\+/g,'-').replace(/\//g,'_').replace(/=+$/,'') }

async function etag(body: ArrayBuffer): Promise<string> {
  const d = await crypto.subtle.digest('SHA-256', body)
  return 'W/"' + b64url(d) + '"'
}

function ttlValid(ttl: number): boolean { return Number.isInteger(ttl) && ttl >= 0 && ttl <= 86400 }

缓存策略分配

type Req = { path: string; userSpecific?: boolean }
type Res = { setHeader: (k: string, v: string) => void; end: (b?: string) => void }

function isVersioned(path: string): boolean { return /\.[a-f0-9]{8,}\./.test(path) }
function isStatic(path: string): boolean { return /\.(js|css|png|jpg|svg|woff2)$/.test(path) }

async function setCacheHeaders(req: Req, res: Res, body: ArrayBuffer) {
  res.setHeader('X-Content-Type-Options', 'nosniff')
  res.setHeader('Vary', 'Accept-Encoding')

  if (req.userSpecific) {
    res.setHeader('Cache-Control', 'private, no-store')
    return
  }

  if (isStatic(req.path) && isVersioned(req.path)) {
    res.setHeader('Cache-Control', 'public, max-age=31536000, immutable')
    const t = await etag(body)
    res.setHeader('ETag', t)
    return
  }

  const ttl = 60
  if (!ttlValid(ttl)) {
    res.setHeader('Cache-Control', 'no-store')
    return
  }
  res.setHeader('Cache-Control', `public, max-age=${ttl}, s-maxage=${ttl}`)
  const t = await etag(body)
  res.setHeader('ETag', t)
}

落地建议

  • 静态资源启用版本化命名并配置长TTL与 immutable,动态接口按短TTL或不缓存。
  • 用户态或敏感信息全部使用 private, no-store,避免代理与浏览器缓存。
  • 严格校验TTL上限并统一生成弱ETag以减少不必要重验证。
  • 配置 Vary: Accept-Encodingnosniff,确保压缩与类型安全。

验证清单

  • 版本化静态是否命中长TTL与 immutable,ETag是否生成。
  • 动态接口是否统一短TTL或不缓存,用户态是否 no-store
  • Varynosniff 是否统一下发。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部