强缓存和协商缓存

了解缓存机制

Posted by LBX on July 18, 2023

浏览器会根据请求头Expires或者Cache-Control: max-age指定的时间来判断是否命中强缓存。如果命中了则直接加载缓存中的资源,请求并不会发送到服务器,返回200 OK状态码。

如果未命中强缓存,浏览器会将请求发送给服务器,服务器来判断本地缓存是否有效,如果可以使用则不会返回资源,而是由浏览器从缓存中取出资源并返回,此时返回状态码304 Not Modified;如果未命中协商缓存,则服务器会将完整的资源返回给浏览器,浏览器获取到新资源,返回给用户,状态码200 OK,浏览器更新缓存

强缓存

说到强缓存,就不得不说的头部字段Expires/Cache-Control

Expires: 实体主体过期的日期时间,Expires: <date> GMT格式

Cache-Control:max-age字段值,指定了实体主体会在多久后过期,单位为秒

Cache-Control: s-maxage字段值,与max-age作用相同

在http1.0中,Expires: <date> GMT格式优先级高于Cache-Control: max-age=10000,在http1.1中相反,推荐使用Cache-Control指定控制缓存行为,因为Expires的字段值为GMT格式的日期,不准确

1
2
http1.1中优先级顺序为:s-maxage > max-age > Expires
http1.0中优先级顺序为:Expires > s-maxage > max-age

max-age用于指定任何缓存(包括中间缓存)可以缓存资源的最长时间。s-maxage指定仅适用于共享缓存,例如代理服务器,用于指定共享缓存可以缓存资源的最长时间。max-age更多的是通过控制客户端缓存可以缓存资源的时间来优化web性能。虽然max-age仍有安全隐患

总结:推荐使用Cache-Control: max-age=xxx 来控制缓存过期时间

协商缓存

当没有命中强缓存,就会走协商缓存

协商缓存对应的头部信息

  • Last-Modified/If-Modified-Since
  • ETag/If-None-Match

Last-Modified和ETag均为响应头,If-Modified-Since和If-None-Match均为请求头

以下步骤不考虑是否命中强缓存:

  1. 当客户端像服务器首次发送请求的时候,服务器会返回Last-Modified(最后更新时间,GMT格式日期时间)和ETag(资源唯一标识符)
  2. 再次进行请求,客户端在请求头中指定If-Modified-Since字段,字段值为服务器之前返回的Last-Modified字段值,If-None-Match请求头字段值为服务器之前返回的ETag响应头字段值
  3. 如果同时指定两个请求头,ETag比If-Modified-Since优先级要高,所以会首先判断客户端所请求资源的ETag值是否与请求头If-None-Match的字段值一致,如果一致的话,会在进行判断If-Modified-Since字段值,如果在指定日期之后被修改过,就会再次返回资源,状态码200 OK,如果没有被修改过,则返回304 Not Modified

流程图如下:

参考:

  1. http请求头整理