一、Cache-Cantrol
-
max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。
比如一个css资源,max-age=2592000,也就是说缓存有效期为2592000秒(也就是30天),会配合Date属性。于是在30天内都会使用这个版本的资源,即使服务器上的资源发生了变化,浏览器也不会得到通知。max-age会覆盖掉Expires,后面会有讨论。
读取缓存数据条件:上次缓存时间(客户端的)+max-age < 当前时间(客户端的) -
s-maxage(单位为s)同max-age,只用于共享缓存(比如CDN缓存)。
比如,当s-maxage=60时,在这60秒中,即使更新了CDN的内容,浏览器也不会进行请求。也就是说max-age用于普通缓存,而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖掉max-age和Expires header。 - public 指定响应会被缓存,并且在多用户(不同的窗口)间共享。如果没有指定public还是private,则默认为public。
- private 响应只作为私有的缓存,不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。private 响应只能在私有缓存中被缓存,不能放在代理缓存上。对一些用户信息敏感的资源,通常需要设置为private。
- no-cache 指定不缓存响应,表明资源不进行缓存,但是设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。因此有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。
- no-store 绝对禁止缓存,一看就知道如果用了这个命令当然就是不会进行缓存啦~每次请求资源都要从服务器重新获取。
- must-revalidate 指定如果页面是过期的,则去服务器进行获取。这个指令并不常用,就不做过多的讨论了。
二、Expires
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过,cache-control的优先级更高。 Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
Expires是较老的强缓存管理header,由于它是服务器返回的一个绝对时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如时钟不同步,或者跨时区),那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。
Cache-Control描述的是一个相对时间,在进行缓存命中的时候,都是利用客户端时间进行判断,所以相比较Expires,Cache-Control的缓存管理更有效,安全一些。
三、Last-modified
服务器端文件的最后修改时间,需要和cache-control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。
四、ETag
根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改,如果没有修改,过程如下:
使用ETag可以解决Last-modified存在的一些问题:
- 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新
- 如果资源修改非常频繁,在秒以下的时间内进行修改,而Last-modified只能精确到秒
- 一些资源的最后修改时间改变了,但是内容没改变,使用ETag就认为资源还是没有修改的。
补充
- HTTP通过缓存将服务器资源的副本保留一段时间,这段时间称为新鲜度限值。这在一段时间内请求相同资源不会再通过服务器。HTTP协议中Cache-Control 和 Expires可以用来设置新鲜度的限值,前者是HTTP1.1中新增的响应头,后者是HTTP1.0中的响应头。二者所做的事时都是相同的,但由于Cache-Control使用的是相对时间,而Expires可能存在客户端与服务器端时间不一样的问题,所以我们更倾向于选择Cache-Control。
-
优先级
Etag比Last-modified 可靠,哪怕是打开文件再直接进行保存也会刷新Last-modified时间,Cache-Control >Expires。 - 强缓存和弱缓存区分。强缓存会直接读取浏览器缓存,如Cache-Control、Expires。弱缓存向服务端发出请求,若未修改资源返回304,若资源已更新返回正常的200。Last-modified和ETag属于弱缓存。Expires和Last-modified都需要配合Cache-Control使用,会先判断强缓存是否失效,失效才会需要弱缓存。