欢迎光临本地信息咨询网
详情描述

HTTP缓存是Web开发面试中高频且核心的考点,理解它对于优化性能和解决问题至关重要。下面我将以面试回答的形式,为你系统解析HTTP缓存。

一、核心概念(一句话开场)

HTTP缓存是一种通过存储资源副本并在后续请求中复用的技术,旨在显著减少网络延迟、降低服务器负载、提升用户体验。

二、缓存位置(从哪里读缓存?)

强缓存(本地缓存)

  • 浏览器缓存:直接从内存或磁盘读取,速度最快。
  • 命中时,状态码为 200 (from memory/disk cache)完全不发送请求到服务器。

协商缓存(对比缓存)

  • 浏览器必须向服务器发送请求,验证本地副本是否仍可用。
  • 如果可用(缓存有效),服务器返回 304 Not Modified,浏览器使用本地缓存。
  • 如果不可用,服务器返回 200 和新资源。

三、关键HTTP头字段(如何控制缓存?)

这是面试重点,需要分两类说清楚。

1. 强缓存相关字段

浏览器检查这两个字段,决定是否使用强缓存。优先级:Cache-Control > Expires

  • Cache-Control (HTTP/1.1, 相对时间,优先级高)

    • max-age=3600: 资源有效期为3600秒。
    • no-cache跳过强缓存,直接进入协商缓存流程。
    • no-store彻底禁用所有缓存,每次都要从服务器获取。
    • public: 允许代理服务器缓存。
    • private: 仅允许浏览器缓存。
    • immutable: 资源永不变,用户刷新也不发送验证。
  • Expires (HTTP/1.0, 绝对时间)

    • 指定资源过期的具体日期/时间。
    • 缺点:依赖客户端时间,时间不准会导致缓存错乱。
2. 协商缓存相关字段

成对出现,由服务器返回,用于验证。

  • Last-Modified / If-Modified-Since (基于修改时间)

    • 服务器在响应头中返回 Last-Modified (资源最后修改时间)。
    • 浏览器下次请求时,在请求头中带上 If-Modified-Since (这个时间)。
    • 服务器比较时间,如果没变,则返回 304
    • 缺点:精度到秒;文件可能只是被touch,内容未变;分布式服务器时间可能不同步。
  • ETag / If-None-Match (基于资源标识,优先级更高)

    • 服务器在响应头中返回 ETag (通常是文件内容的哈希值,如 W/"xyz123")。
    • 浏览器下次请求时,在请求头中带上 If-None-Match (这个ETag值)。
    • 服务器比较ETag,如果匹配,则返回 304
    • 优势:比时间更精准,能感知内容是否真变化。

四、完整的缓存决策流程图(必背!)

你可以这样描述或画图:

1. 浏览器发起资源请求。
2. 检查是否有强缓存(Cache-Control/Expires)。
   └─ 若有,且未过期 -> 直接从缓存读取 (200 from cache),流程结束。
   └─ 若没有或已过期 -> 进入步骤3。
3. 浏览器准备发起请求,检查是否有协商缓存标识(Last-Modified/ETag)。
   └─ 若没有 -> 直接向服务器请求新资源 (200)。
   └─ 若有 -> 在请求头中带上 `If-Modified-Since` 或 `If-None-Match`。
4. 服务器收到请求,验证缓存是否有效。
   └─ 若有效 -> 返回 304 Not Modified,浏览器使用本地缓存。
   └─ 若无效 -> 返回 200 和新资源,并更新响应头的缓存标识。

五、实际应用策略(如何配置?)

这是体现你工程能力的地方。

  • 不常变的静态资源(如JS/CSS库、图片)

    Cache-Control: public, max-age=31536000, immutable

    说明:设置超长缓存(1年),并加immutable避免用户刷新也请求。通过修改文件名(如添加hash指纹) 来强制更新。

  • 经常变动的资源(如HTML、API接口)

    Cache-Control: no-cache

    说明:让浏览器每次都和服务端验证,确保获取最新内容。

  • 私有或敏感数据

    Cache-Control: private, no-store

    说明:禁止任何缓存。

六、常见面试题(举一反三)

用户点击“刷新”按钮和“强制刷新”(Ctrl+F5)有什么区别?

  • 普通刷新:会走正常的缓存流程(强缓存 -> 协商缓存)。
  • 强制刷新:浏览器会在请求头中带上 Cache-Control: no-cache(甚至Pragma: no-cache),跳过所有缓存,直接从服务器获取。

为什么有了Last-Modified还要ETag?

  • 回答:解决Last-Modified的三个痛点(秒级精度、内容未变但时间变、服务器时间同步问题)。ETag能更精准地判断内容是否变化。

缓存存在哪里?内存和硬盘有什么区别?

  • 内存缓存:快速,但关闭Tab/浏览器可能失效。小资源、当前会话高频资源。
  • 磁盘缓存:持久化,容量大。大资源、低频资源。

如何更新一个被强缓存的资源?

  • 答案:改变资源的URL。最常用的是在文件名中嵌入内容哈希(如 app.a1b2c3.js),或添加版本号参数(?v=2)。这样会作为新资源请求。

CDN缓存和浏览器缓存是什么关系?

  • CDN是位于浏览器和源站之间的“超级缓存”。CDN节点也会遵循HTTP缓存规则。通常CDN会缓存 public 资源,并通过其自身的策略(如X-Cache)来管理。

七、回答技巧总结

  • 结构化:按“是什么 -> 在哪 -> 怎么控制 -> 怎么用”的逻辑展开。
  • 抓重点:清晰区分强缓存协商缓存的流程和字段。
  • 懂原理:能说出 ETagLast-Modified 好的原因。
  • 重实践:能给出不同场景下的配置策略,并说明“文件哈希”在缓存更新中的核心作用。

掌握以上内容,你不仅能应对绝大多数HTTP缓存的面试问题,还能展现出你对Web性能优化的深入理解。