浏览器会根据请求头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均为请求头
以下步骤不考虑是否命中强缓存:
- 当客户端像服务器首次发送请求的时候,服务器会返回Last-Modified(最后更新时间,GMT格式日期时间)和ETag(资源唯一标识符)
- 再次进行请求,客户端在请求头中指定If-Modified-Since字段,字段值为服务器之前返回的Last-Modified字段值,If-None-Match请求头字段值为服务器之前返回的ETag响应头字段值
- 如果同时指定两个请求头,ETag比If-Modified-Since优先级要高,所以会首先判断客户端所请求资源的ETag值是否与请求头If-None-Match的字段值一致,如果一致的话,会在进行判断If-Modified-Since字段值,如果在指定日期之后被修改过,就会再次返回资源,状态码200 OK,如果没有被修改过,则返回304 Not Modified
流程图如下:
参考: