缓存机制
参考地址:zhuanlan.zhihu.com/p/25953524
缓存类型
强缓存:不会向服务器发送请求,直接从缓存中读取资源
协商缓存:向服务器发送请求,服务器会根据这个请求的request header的一些参数来判断是否命中协商缓存,如果命中,则返回304状态码并带上新的response header通知浏览器从缓存中读取资源
共同点:都是从客户端缓存中读取资源;区别是强缓存不会发请求,协商缓存会发请求。
强缓存
Expires:response header里的过期时间,浏览器再次加载资源时,如果在这个过期时间内,则命中强缓存。
Cache-Control:当值设为max-age=300时,则代表在这个请求正确返回时间(浏览器也会记录下来)的5分钟内再次加载资源,就会命中强缓存。
-
两者作用相同
-
Expires 是http1.0的产物,Cache-Control是http1.1的产物,两者同时存在的话,Cache-Control优先级高于Expires;在某些不支持HTTP1.1的环境下,Expires就会发挥用处。所以Expires其实是过时的产物,现阶段它的存在只是一种兼容性的写法
-
Expires是一个具体的服务器时间(如下图),这就导致一个问题,如果客户端时间和服务器时间相差较大,缓存命中与否就不是开发者所期望的,并且 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。Cache-Control是一个时间段,控制就比较容易。
-
协商缓存
ETag和If-None-Match:Etag是上一次加载资源时,服务器返回的response header,是对该资源的一种唯一标识,只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器接受到If-None-Match的值后,会拿来跟该资源文件的Etag值做比较,如果相同,则表示资源文件没有发生改变,命中协商缓存。
Last-Modified和If-Modified-Since:Last-Modified是该资源文件最后一次更改时间,服务器会在response header里返回,同时浏览器会将这个值保存起来,在下一次发送请求时,放到request header里的If-Modified-Since里,服务器在接收到后也会做比对,如果相同则命中协商缓存。
-
两者作用相同
- 精确度上,Etag要优于Last-Modified。Last-Modified的时间单位是秒,如果某个文件在1秒内改变了多次,那么他们的Last-Modified其实并没有体现出来修改,但是Etag每次都会改变确保了精度
- Etag优先级高于Last-Modified
使用场景
1.Expires: Wed, 22 Oct 2018 08:41:00 GMT // 该事件后过期
2.Cache-control: max-age=30 // 30s后过期
3.Cache-control: no-store // 不缓存
4.对于频繁变动的资源,可以使用 Cache-Control: no-cache 并配合 ETag 使用,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新。
注意:no-store是客户端不缓存,no-cache是客户端要缓存但是每次都会向先询问服务端资源是否更新,即协商缓存
缓存过程
以下图片为搬运