参考 (opens new window)

网络方面的缓存分为三块:DNS缓存HTTP缓存CDN缓存,也有人把这里的 HTTP 缓存称为浏览器缓存。

还有本地的就是:浏览器的本地存储离线存储,更快提高首屏加载速度,让页面飞起

# 1、DNS缓存

进入页面的时候会进行DNS查询,找到域名对应的服务器的IP地址,再发送请求

# 2、HTTP缓存

就是将http请求获取的页面资源存储在本地,之后再加载直接从缓存中获取而不用请求服务器,从而响应更快。先看图:

# 2-1、强缓存

  • 强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程,强制缓存的情况主要有三种

1.不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求(跟第一次发起请求一致),如下图:

2.存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存(暂不分析),如下图

3.存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果,如下图

控制强制缓存的字段分别是Expires和Cache-Control,其中Cache-Control优先级比Expires高。

# Expires:用来指定资源到期绝对时间,服务器响应时,添加在响应头中。

expires: Wed, 22 Nov 2021 08:41:00 GMT
1

注意:如果服务器和浏览器端时间不一致的话可能导致失败。
比如现在时间是8月1,expires过期时间是8月2,客户端把电脑时间改成了8月3,那就用不了这个缓存

# Cache-Control:指定资源过期时间秒,如下,表示在这个请求正确返回后的300秒内,资源可以使用,否则过期。添加在响应头中。

cache-control:max-age=300
1

Expires 和 Cache-Control 的区别

1、Expires 是HTTP/1.0中的,Cache-Control 是HTTP/1.1中的;
2、两者同时存在的话 Cache-Control 优先级高于 Expires;

强缓存的缺点:

就是缓存过期之后,不管资源有没有变化,都会重新发起请求,重新获取资源
而实际情况是在资源文件没有更新的情况下,即使过期了也不重新获取资源,继续使用旧资源,
所以协商缓存它来了,在强缓存过期的情况下,再走协商缓存的流程,判断文件有没有更新。

  • Cache-Control 缓存能力指令
指令 说明
public 响应可以被任何缓存(浏览器、CDN、代理服务器等)缓存
private 响应只能被单个用户的浏览器缓存,不允许共享缓存(如CDN)存储
no-store 禁止缓存任何响应内容(最严格的限制)
no-cache 可以缓存但每次使用前必须向服务器验证(不是"不缓存"的意思)
must-revalidate 缓存必须在使用前验证过期资源,不可使用过期资源
  • Cache-Control 缓存期限指令
指令 说明
max-age=<seconds> 资源被视为新鲜的最长时间(秒)
immutable 表示资源永不过期,减少验证请求(适用于带哈希的静态资源)
  • Cache-Control 指令组合示例
  1. 静态资源长期缓存,适用于带内容哈希的文件(如 style.a1b2c3d4.css)
Cache-Control: public, max-age=31536000, immutable
1
  1. 动态内容短时缓存,适用于个性化内容,每10分钟验证一次
Cache-Control: private, no-cache, max-age=600
1
  1. 敏感内容禁止缓存,适用于银行交易、登录页面等
Cache-Control: no-store
1

# 2-2、协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程,主要有以下两种情况:

1.协商缓存生效,返回304,如下

2.协商缓存失效,返回200和请求结果结果,如下

控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match
其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

# 2-2-1、Last-Modified/If-Modified-Since

第一次请求资源时,服务器除了会返回给浏览器上面说的过期时间,还会在响应头添加 Last-Modified 字段,告诉浏览器该资源的最后修改时间

last-modified: Fri, 27 Oct 2021 08:35:57 GMT
1

然后浏览器再次请求的时候就把这个时间再通过另一个字段 If-Modified-Since 添加到请求头,发送给服务器

if-modified-since: Fri, 27 Oct 2021 08:35:57 GMT
1

服务器再把这两个字段的时间对比,如果是一样的,就说明文件没有被更新过,就返回状态码304和空响应体给浏览器,浏览器直接拿过期了的资源继续使用即可;如果对比不一样说明资源有更新,就返回状态码200和新的资源。

所以说 Last-Modified/If-Modified-Since 是成对的,是为了对比文件修改时间

Last-Modified/If-Modified-Since的缺点:

1、如果本地打开了缓存文件,即使没有对文件进行修改,但还是会造成Last-Modified被修改,服务器端不能命中缓存导致发送相同资源
2、因为Last-Modified只能以秒计时,如果在不可感知的时间内修改了文件,服务器端会认为还是命中了,无法返回正确的资源
3、如果资源有周期性变化,如资源修改后,在一个周期内又改回了原来的样子,我们认为这个周期前的缓存是可以使用的,但是Last-Modified不这样认为

# 2-2-2、ETag/If-None-Match

第一次请求资源时,服务器除了会在响应头上返回Expires、Cache-Control、Last-Modified,还在返回Etag字段,表示当前资源文件的一个唯一标识。

这个标识符由服务器基于文件内容编码生成,能精准感知文件的变化,只要文件内容不同,ETag就会重新生成

etag: W/"132489-1627839023000"
1

然后浏览器再次请求的时候就把这个文件标识 再通过另一个字段 If-None-Match,发送给服务器

if-none-match: W/"132489-1627839023000"
1

服务器再把这两个字段对比,如果发现是一样的,就说明文件没有被更新过,就返回状态码304和空响应体给浏览器,浏览器直接拿过期了的资源继续使用;
如果对比不一样说明资源有更新,就返回状态码200和新的资源。

  • ETag 的生成方式
      1. 基于内容哈希(最常用)
      1. 基于文件系统属性
      1. 基于数据库字段
      1. 基于时间戳(简单实现)

Last-Modified 和 ETag 的区别:

1、Etag 感知文件精准度要高于 Last-Modified
2、同时使用时,服务器校验优先级 Etag/If-None-Match
3、Last-Modified 性能上要优于 Etag,因为 Etag 生成过程中需要服务器付出额外开销,会影响服务器端的性能,所以它并不能完全替代 Last-Modified,只能作为补充和强化

Nginx 默认ETag生成

Nginx 使用最后修改时间+内容长度的十六进制组合:

ETag: "5d8c72a5-264"  # 格式:修改时间-内容长度
1

# 强缓存与协商缓存的区别:

  • 优先查找强缓存,没有命中再查找协商缓存
  • 强缓存不发请求到服务器,所以有时候资源更新了浏览器还不知道,但是协商缓存会发请求到服务器,资源是否有更新,服务器肯定知道
  • 目前项目大多数使用缓存的方案
    1、协商缓存一般存储:HTML
    2、强缓存一般存储:css, image, js,文件名带上 hash

# 3、本地缓存

# cookies,sessionStorage 和 localStorage

共同点:都是保存在浏览器端,且同源的

特性​ ​​Cookies​ ​​sessionStorage​ ​​localStorage​
​​存储容量​ 每个域名约 50-150 个, 4KB 左右 5-10MB(不同浏览器不同) 5-10MB(甚至更大)
生命周期​ 可设置过期时间(默认会话级,关闭浏览器后清除)
通过 expires 或 max-age 设置过期时间
​​会话级​​(关闭标签页清除) ​永久存储​​(需手动清除)
作用域​ 同域名下所有标签页共享 ​仅当前标签页​ 同域名下所有标签页共享
同步行为 修改后立即同步 完全不共享 需通过 storage 事件监听同步
​​是否随请求发送​ 是(自动附加到 HTTP 请求头)
​典型用途 用户认证、会话跟踪 临时表单数据、页面间传参 长期存储(如用户偏好设置)
删除单个数据 设置过期时间为过去或 Max-Age=0 removeItem(key) removeItem(key)
清空所有数据 遍历所有Cookie逐个删除 clear() clear()
自动失效机制 依赖 Expires/Max-Age 设置 标签页关闭自动清除 无,需手动或程序控制
安全注意事项 敏感数据应标记 HttpOnly 和 Secure(防止 XSS 和嗅探) 不要存储敏感信息(如密码),易受 XSS 攻击 不要存储敏感信息(如密码),易受 XSS 攻击

更详细参考 (opens new window)

lastUpdate: 5/23/2025, 5:45:51 PM