HTTP 强缓存vs弱缓存

HTTP缓存

类型

  • 强缓存(本地缓存)
  • 弱缓存(协商缓存)

流程

访问静态资源时的流程

  1. 强缓存阶段:先在本地查找是否有该资源,若有,且ExpiresCache-Control都满足要求,则命中强缓存,返回200,直接返回强缓存中的数据,不会向服务器发出请求。
  2. 弱缓存阶段:在本地缓存找到该资源,发送http请求到服务器询问该资源是否有更新,若服务器判断没有更新,返回304Not Modified。则浏览器继续使用该资源。
  3. 缓存失败阶段:若在本地没有找到对应资源,或者资源已过期/更新,则服务器返回该资源。

强缓存VS弱缓存

  • 状态码
    强缓存返回200
    弱缓存返回304
  • 强缓存不需要发出http请求,而弱缓存需要。

强缓存

使用Expirescache-control来控制。优先级:pragma>cache-control>Expires

  • Expires

    服务器为资源设置一个Expire日期,在这Expire日期之前可以将资源视作最新。此字段是为了兼容旧版本HTTP才保留的,在http1.0时配合pragma使用,pragma:no-cache表示不缓存,pragma的优先级大于Expires

  • Cache-Control

    Cache-Controlhttp1.1为了弥补Expires的缺陷而加入的(http1.0时,使用pragma),当ExpiresCache-Control同时存在时,Cache-Control的优先级高于Expires

Cache-Control取值 描述
public 服务器端和浏览器端都可以缓存
private 只有浏览器可以缓存
no-cache 强制浏览器在使用cache拷贝之前先提交一个http请求到原服务器进行确认,类似于弱缓存
only-if-cached 表明客户端只接受已缓存的响应,并且不需要向服务器检查是否有更新的拷贝
max-age=60 单位:秒,缓存的有效期,超过这个时间后将被认为过期。此选项会覆盖Expires字段的过期日期
no-store 不缓存,使用协商缓存
must-revalidate 缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源

弱缓存

有关字段 Last-Modified/If-Modified-Since(HTTP1.0)、Etag/If-None-Match(HTTP1.1)

  • Last-ModifiedEtag为响应头部字段,分别对应请求头部字段中的if-Modifed-Since/If-None-Match

Last-Modified/If-Modified-Since存在缺陷,当资源的实际内容没有改变而仅仅只是时间变化了(比如只是打开了文件,并保存了一下,尽管内容没有变化但还是修改过),还是需要重新请求资源。因此为了解决这个缺陷,http1.1提出了Etag/If-None-MatchEtag类似于文件的hash,为文件提供了一个指纹,只检查文件内容是否一致。

流程:

  1. 当没有命中强缓存时,进入弱缓存阶段
  2. 浏览器首次访问网站时,服务器会在响应头部中附上Last-Modified/Etag
  3. 弱缓存阶段,浏览器再次访问时,会发送If-Modified-Since/If-None-Match去询问是否有改变,有则重新获取,否则使用本地缓存。

缓存与浏览器刷新

  • F5刷新,会使强缓存失效,浏览器进行协商缓存。
  • Ctrl+F5刷新,为强制刷新,强缓存与弱缓存均失效,浏览器总会发送HTTP请求向服务器获取最新数据。