http缓存技术/浏览器缓存机制有哪些?

193 阅读5分钟

浏览器缓存通过 强缓存协商缓存 机制优化性能: 浏览器缓存是指将请求响应的数据存放在本地,通过缓存机制来提升效率优化性能。

  1. 强缓存 由无需网络请求,由响应头字段 Cache-Control相对时间有效期(优先级高更加精细,如 max-age=3600) 和 Expires绝对时间有效期来控制,浏览器访问服务器资源时,会先让请求时间和相对时间有效期进行对比,如果没过期,直接返回本地缓存(状态码 200 from cache),适用于静态资源(如图片/CSS/JS);
  2. 当强缓存失效时,触发 协商缓存:需要网络验证,有两种方式来实现:

2.1. 通过请求头字段 If-Modified-Since字段(对应响应头 Last-Modified字段)来实现的。当资源过期了,发现响应头里面有last-modified最新修改时间,再发请求的时候就会带上if 和 last发过去,当服务器发现有if-modifed-since字段传过来就会校验传过来的最新修改时间,如果传过来的小,就说明资源修改了,就返回最新资源,如果传过来的大,说明资源没被修改,就返回304复用本地缓存。

2.2 通过请求头字段If-None-Match字段(对应响应头 ETag字段) 来实现的。当资源过期了,返现响应头里面有etag字段也就是唯一标识响应资源,再发请求时会将if和etag发过去,当服务器发现有if字段传过来就会判断etag是否发生变化,若资源未修改则返回 304 Not Modified(复用本地缓存),否则返回 200 和新数据;

然后就是etag唯一标识资源的优先级要比last-modified最新修改时间的优先级要高,优化了last-mofidied的一些缺陷:1.没有修改文件内容的情况下也就是说etag没变的情况下,最后的修改时间last-modified也可能改变,就会进行重新请求响应,浪费资源。2.然后就是if-modified-since能查到的粒度是秒级的,而有些文件的修改可能是秒级以内的,这种modified就发现不了服务端资源的修改,而etag唯一标识响应资源就能发现,一秒内能刷新多次。3最后就是服务器并不能精确获取文件的最后修改时间而能精确获取etag的变化。

  1. 实际开发中,静态资源建议设置长期强缓存(文件名哈希化),HTML 文件禁用缓存(Cache-Control: no-cache),敏感数据用 no-store 彻底禁用;
  2. 性能与安全平衡:ETag 比 Last-Modified 更精准(内容哈希 vs 时间戳),但需注意集群服务器的哈希一致性。

一、缓存机制全景图(必考流程图)

        [浏览器请求]
           │
           ▼
   ┌─ 强缓存是否有效?─┐
   │(检查Cache-Control/Expires)│
   └───────────────┘
           │
  有效 ▼           无效 ▼
 [直接200(from cache)][发起请求到服务器]
                               │
                               ▼
                   ┌─ 协商缓存是否有效?─┐
                   │(检查ETag/Last-Modified)│
                   └───────────────┘
                               │
                  有效 ▼           无效 ▼
                [304 Not Modified]    [200 OK + 新数据]

二、核心缓存策略(3层递进)

1. 强缓存(无需网络请求)

  • 响应头控制
    Cache-Control: max-age=3600  // 相对时间(优先级高)
    Expires: Wed, 21 Oct 2024 07:28:00 GMT  // 绝对时间(兼容旧系统)
    
  • 典型场景
    • 静态资源(图片/CSS/JS)配置长期缓存(如max-age=31536000

2. 协商缓存(需网络验证)

  • 校验头组合
    # 第一次响应
    Last-Modified: Fri, 12 Jul 2024 10:30:00 GMT
    ETag: "abc123"
    
    # 后续请求
    If-Modified-Since: Fri, 12 Jul 2024 10:30:00 GMT
    If-None-Match: "abc123"
    
  • 工作逻辑
    • 服务器对比时间戳(Last-Modified)或内容哈希(ETag)
    • 未修改 → 返回304(省流量)
    • 已修改 → 返回200 + 新数据

3. 缓存禁用策略

Cache-Control: no-store        // 彻底禁用缓存(敏感数据)
Cache-Control: no-cache        // 每次必须验证(类似协商缓存)

三、实战配置指南(前端必会)

1. 静态资源长期缓存

# Nginx配置示例
location /static {
  add_header Cache-Control "public, max-age=31536000, immutable";
}
  • 最佳实践:文件名带hash(如app.a1b2c3.js),内容变化自动更新URL

2. HTML文件禁用强缓存

<!-- 防止页面更新不及时 -->
<meta http-equiv="Cache-Control" content="no-cache">

3. API数据缓存策略

# 适合频繁读取的配置
Cache-Control: private, max-age=60  // 客户端缓存1分钟

四、高频考点解析

1. 缓存优先级

强缓存 > 协商缓存 > 实际请求
(先检查本地是否可用,再检查是否过期)

2. ETag vs Last-Modified

ETagLast-Modified
精度内容哈希(精确到字节变化)时间戳(秒级精度)
典型场景频繁编辑的文件(如wiki页面)低频修改的资源(如新闻稿)

3. 状态码304的特殊性

  • 不返回body数据(节省带宽)
  • 触发浏览器更新本地缓存过期时间

五、记忆口诀

"强缓存优先查,过期转协商,
ETag精度高,304省流量,
静态资源配哈希,敏感数据no-store"

掌握这些要点,面试遇到缓存问题就能对答如流! 🚀