服务器可以在响应中返回 ETag,然后浏览器会在后续的请求中携带上这个参数来确定缓存是否需要更新。如果 ETag 值相同,说明资源未更改,服务器会返回 304(Not Modified) 响应码,浏览器就知道本地缓存仍然是可以使用的。
image
不过需要注意的是,ETag 只有在本地缓存已过期(Expires)或者缓存模式设置为 no-cache(Cache-Control)的时候,才会被浏览器携带上与服务器端的值进行判别。
Cache-Control
Cache-Control 可以携带多个响应值,这些值可以设置缓存时间、状态以及验证状态。不同值说明如下。
image
例如,访问某张图片,服务器返回的响应如下:Cache-Control: max-age=691200,则说明这张图片可以在客户端存储 8 天。
Expires
这个响应头标记了数据的过期时间,超过其中规定的时间后,缓存会被定义为过期。例如:Expires: Sat, 27 Apr 2019 11:43:15 GMT
说明对应的数据会在 2019 年 4 月 27 号的 11 点 43 分后过期。
需要注意的是,如果 Cache-Control 中有 max-age 指令,浏览器会忽略此参数。
Last-Modified
服务器可以通过配置这个响应头,来向浏览器发送一个数据上次被修改的时间标签,例如:Last-Modified:Wed, 24 Apr 2019 02:54:16 GMT
这样浏览器就知道了该数据最后被修改的时间,后续请求中,会和服务器进行时间的比较,如果服务器上的时间比本地时间要新,说明数据有更改,浏览器需要重新下载数据。
HTTP 响应示例
接下来我们可以看一个响应示例。
image
第 2 行告诉我们 max-age 是 1 小时;
第 5 行告诉我们这是一张 PNG 图片;
第 7 行向我们显示了 ETag 值,该值将在 1 小时标记后用于验证,以验证资源是否有更改;
第 8 行是 Expires 响应,因为设置了 max-age,它将被浏览器忽略;
第 10 行是 Last-Modified 响应,显示上次修改图像的时间。
浏览器缓存的不足
当服务器返回的响应中有 Expires 或者 Cache-Control 设置了 max-age 响应头的时候,浏览器不会向服务器发起校验请求,而是直接复用本地缓存。如果此时服务器进行了资源的更新,用户就无法获取到最新的资源,只能通过强制刷新浏览器缓存来跟服务器请求最新的资源。
此外,Expires 是服务器返回的一个绝对时间,在服务器时间与客户端时间相差较大时,缓存管理容易出现问题,比如随意修改下客户端时间,就能影响缓存命中的结果。
因此在实际使用过程中,需要灵活使用浏览器的缓存策略。
CDN 缓存介绍当服务接入了 CDN 之后,浏览器本地缓存的资源过期之后,浏览器不是直接向源服务器请求资源,而是转而向 CDN 边缘节点请求资源。CDN 边缘节点中将用户的数据缓存起来,如果 CDN 中的缓存也过期了,CDN 边缘节点会向源服务器发出回源请求,从而来获取最新资源。以下介绍以又拍云 CDN 为例。
CDN 缓存策略