强缓存与协商缓存
一、强缓存
当浏览器请求某个资源时,服务端会在response header中对此资源做缓存配置,缓存的时间和类型都由服务端配置。
response header的cache-control,常见的设置有max-age,public,immutable.private,no-cache,no-store
如下图cache-controle的设置,其中:
max-age表示缓存的时间是315360000秒(10年);
public表示可被客户端或者代理服务(nginx)器缓存(与其对应的是private,只可以被客户端缓存);
immutable表示资源在设定的时间内永远不变,即使刷新浏览器也不会重新请求该资源(相反如果没此属性,当用户刷新页面时,会重新发送请求,获取该资源,这就是额外的请求消耗了)
image.png
1、cache-control: max-age=xxxx,public
客户端和代理服务器都可以缓存该资源;
客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,如果用户做了刷新操作,就向服务器发起http请求
2、cache-control: max-age=xxxx,private
只让客户端可以缓存该资源;代理服务器不缓存
客户端在xxx秒内直接读取缓存,statu code:200
3、cache-control: max-age=xxxx,immutable
客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,即使用户做了刷新操作,也不向服务器发起http请求
4、cache-control: no-cache
跳过设置强缓存,但是不妨碍设置协商缓存;一般如果你做了强缓存,只有在强缓存失效了才走协商缓存的,设置了no-cache就不会走强缓存了,每次请求都回询问服务端。
5、cache-control: no-store
不缓存,这个会让客户端、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。
二、协商缓存
某天客户端发现资源过期,需要重新请求服务器,这时请求的过程就可以设置协商缓存。
协商缓存的设置:
response header :
etag:5c20abbd-e2e8(文件的唯一标识,就是文件的hash)
last-modified:Mon, 24 Dec 2018 09:49:49 GMT(文件的最近更新时间,精确到秒)
流程:
image.png
注意:response header中的etag、last-modified在客户端重新向服务端发起请求时,会在request header中换个key名:
response header(request header):
etag(if-none-matched)
last-modified(if-modified-since)
为什么要有etag?
你可能会觉得使用last-modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要etag呢?HTTP1.1中etag的出现(也就是说,etag是新增的,为了解决之前只有If-Modified的缺点)主要是为了解决几个last-modified比较难解决的问题:
1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新get;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),if-modified-since能检查到的粒度是秒级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
3、某些服务器不能精确的得到文件的最后修改时间。