1、缓存的分类
客户端缓存分为强缓存和协商缓存,它们之间最重要的区别是强缓存不会发起网络请求,而协商缓存会发起网络请求
- 强缓存:如果强缓存命中,则浏览器从自身的缓存中获取资源,不会发起请求到服务端。从网络请求中可以看到size列为memory cache或者disk cache。
强缓存可以通过HTTP头部的Expires和Cache-Control字段来控制。
Expires是浏览器返回的一个绝对时间,表示资源的过期时间,但这存在服务器时间和客户端时间不一致的问题,所以在HTTP1.1之后,就使用Cache-Control:max-age=xx秒来代替Expires
Cache-Control:max-age=xx秒是浏览器返回的资源多久之后过期,是一个相对时间,更方便准确。如果同时设置了这两个头部信息,会以Cache-Control为主
tip:memory cache和disk cache的区别:
memory cache | 从内存中获取资源,不会请求服务器,当关闭页面时会释放掉该内存,再次打开时不会出现memory cache的情况。一般脚本、字体、图片会存在内存中,因为脚本随时都可能会执行,如果放在硬盘里会增加I/O开销。 |
disk cache | 从硬盘中获取资源,不会缓存到内存中,不会请求服务器,样式表一般放在硬盘中,因为css样式加载一次即可渲染出页面。 |
- 协商缓存
当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,通过服务端返回的HTTP HEADER验证这个资源是否命中协商缓存,如果命中,服务端会返回304的状态,但不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器又从自己的缓存中加载这个资源,若未命中请求,则会将这个资源返回给客户端,状态码为200。
协商缓存有两种方式:根据文件的修改时间和根据文件的Etag,它们都需要Cache-Control配合使用
根据文件的修改时间:通过HTTP的头部信息Last-Modified/If-Modified-Since来确定是否命中协商缓存,Last-Modified表示这个资源的最后响应时间,是由服务器返回给客户端的。If-Modified-Since:当强缓存没有命中时,浏览器发现资源具有Last-Modified声明,则向服务端发起请求时带上If-Modified-Since,表示本地缓存的该资源最后的修改时间,服务端收到请求后,与资源的最后修改时间进行对比,如果它们一致,则表明资源未修改,返回304,不返回资源数据。如果不一致,则表明资源有修改,则返回200,返回资源数据。
根据文件的Etag:通过HTTP的头部信息Etag/If-None-Match来确定是否命中协商缓存,Etag是服务端返回的当前资源在服务器的唯一标识符,当文件有变化时,Etag也会改变。If-None-Match:当强缓存没有命中时,浏览器发现资源具有Etag声明,则在请求时带上If-None-Match,它表示浏览器缓存的资源的Etag值,服务端收到请求后,与自身的Etag值进行比较,如果一致返回304,如果不一致返回200。
2、浏览器的请求流程图