http缓存策略分为强缓存和协商缓存,这两种缓存策略都是服务端设置 HTTP Header 来实现的。
强缓存
概念: 不请求服务器,直接从浏览器缓存过的本地进行读取。
配置方法:
Expires: 服务端在响应头中Expires设置一个 GMT 格式的到期时间。客户端的本地时间小于响应头的 Expires 时间,那么会从本地进行读取,不会去请求服务器。如果超过了,那么就去请求服务器去获取最新资源。但是就是因为根据本地时间进行判断,本地时间可以随便修改,所以这种缓存机制有漏洞,会与服务端时间有偏差,为了解决这个问题,就出现了下面的 Cache-contorl。
响应头Cache-contorl:
max-age:这个用于设置一个滑动时间,例如设置 max-age=30 表示客户端时间向后滑动30秒,在这30秒内都是强缓存,不会去请求服务器。
s-maxage:这个和上面的一样,只不过这个设置的是代理服务器的缓存时间。
privte:这个表示缓存只能被客户端的浏览器缓存,不能被代理服务器缓存。
public:这个表示缓存既可以被浏览器缓存,也可以被代理服务器缓存。
no-store:这个属性表示不缓存,在任何情况下,都是与服务器进行最新的交互。
no-cache:这个并非不缓存的意思,这个表示强制进行协商缓存,会在下面描述。
协商缓存
概念:在使用本地的缓存之前,会先向服务器发一个请求,与服务器协商当前浏览器的缓存是否已经过期了,如果没过期,那么就使用本地的资源,如果过期了就去请求最新资源。协商缓存主要是解决强缓存资源不能及时更新的问题,协商缓存服务端可以通过2种设置来实现.
last-modified + If-Modified-Since:
响应头设置Cache-Control为no-cache
客户端请求某个文件,服务端会读取这个文件的最后修改时间,然后把这个时间戳设置到响应头的last-modified字段,下次再请求这个文件,请求头会带上If-Modified-Since为接受到last-modified的时间戳,服务端能拿到这个参数进行对比,如果一致,返回304拿缓存,否则,就请求最新的文件。
缺点:
1.因为记录是秒级别的,在1S内多次修改,但是last-modified还是1S开始的时间戳,所以就会判断失误,拿不到最新的资源。
2.将03.jpg修改成04.jpg,再改回03.jpg,文件是没有变化的,但最后修改时间变了,会导致重新拉取最新的资源。
因此就出现了第二种Etag方式
Etag + If-None-Match
服务端根据文件内容生成一个类似于MD5字符串,并设置到请求头Etag字段,客户端收到后
在下次请求时
客户端会同时发送一个If-None-Match,值为获取的Etag字符串(由发起请求的客户端设置),服务端会进行对比,如果一样设置If-None-Match为false返回304拿缓存,否则,If-None-Match设置true拉取最新资源返回200,并设置最新的Etag。