前言
http缓存主要有两种缓存:强缓存和协商缓存(也叫对比缓存)
强缓存优先级 > 协商缓存优先级
正文
强缓存
主要涉及字段
Expires(HTTP/1.0)和Cache-Control(HTTP1.1),其中Cache-Control优先级高于Expires
Expires
响应头,代表该资源的过期时间,值为服务器返回该请求结果缓存的到期时间
Expires: Wed, 22 Oct 2018 08:41:00 GMT
表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。
并且 Expires 受限于客户端时间,如果修改了客户端时间,可能会造成缓存失效。
所以现在 HTTP/1.1中新增了 Cache-Control
Cache-Control
请求/响应头,缓存控制字段,精确控制缓存策略 这里涉及到的字段是max-age,Cache-Control还有其他字段的。
Cache-control: max-age=30
该属性值表示资源会在 30 秒后过期,需要再次请求。也就是说在 30 秒内如果再次发起该请求,则会直接使用缓存,强缓存生效。
对比
- HTTP响应报文中 Expires 的时间值,是一个绝对值
- HTTP响应报文中 Cache-Control为max-age=600 ,是相对值(解决 Expires 受限于客户端时间)
使用时机
以常见的max-age为例:若max-age=5356800,则意思是说浏览器在首次请求这个文件的时候,可以在本地磁盘中保存这个文件5356800秒,从首次加载时间开始以后的这些时间内,若再次请求这个文件,浏览器可以不发起http请求,而直接使用缓存中的内容即可,这样不仅节省了服务器负担,也提升网站用户体验。
协商缓存
如果缓存过期了:
- 没有 Cache-Control 和 Expires
- Cache-Control 和 Expires 过期
- 设置了 no-cache
需要发起请求验证服务资源是否有更新:
- 有更新,返回200,更新缓存
- 无更新,返回304,更新浏览器缓存有效期
主要涉及字段
- Last-Modified 和 If-Modified-Since(HTTP/1.0)
- ETag 和 If-None-Match(HTTP/1.1)
ETag 优先级比 Last-Modified 高
Last-Modified 和 If-Modified-Since
- Last-Modified:响应头,资源最近修改时间,由服务器告诉浏览器
- If-Modified-Since:请求头,资源最近修改时间,由浏览器告诉服务器
Last-Modified
表示本地文件最后修改日期,If-Modified-Since
会将 Last-Modified
的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来,否则返回 304 状态码。
缺点:
- 负载均衡的服务器,各个服务器生成的 Last-Modified 可能有所不同
- GMT 格式有最小单位,例如,如果在一秒内有更改将不能被识别
ETag 和 If-None-Match
为改善在上一组字段中的问题,HTTP/1.1加了这组标记
- Etag:响应头,资源标识,由服务器告诉浏览器
- If-None-Match:请求头,缓存资源标识,由浏览器告诉服务器
ETag 类似于文件指纹,是文件的一个唯一标识序列,当资源有变化时,Etag就会重新生成,If-None-Match 会将当前 ETag 发送给服务器,询问该资源 ETag 是否变动,有变动的话就将新的资源发送回来。
使用 ETag 就可以精确地识别资源的变动情况,就算是秒内的更新,也会让浏览器感知,能够更有效地利用缓存
使用时机
仍然以常见的max-age为例:若max-age=5356800,距离第一次请求文件已经过去了5356800秒,当用户再次需要这个资源的时候,浏览器就会拿之前这个文件返回的Etag以及Last-Modified,分别命名为If-None-Match和If-Modified-Since作为请求参数传给服务端,服务端与现有文件进行匹配,若文件已更新,则返回200状态码,同时返回最新文件给客户端。若文件未更新,则返回304状态码,告诉客户端缓存有效,可以继续使用。