HTTP缓存初探
缓存的作用
用户访问一个web页面的频率远高于web页面更新的频率,因此多数时候用户从服务器获取的html、js、css以及图片等内容都是相同的,如果每次访问都从服务器获取这些静态内容即降低了页面加载的速度,又占用了多余的服务器带宽,显然是一件吃力不讨好的事,此时就需要缓存了。web缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、cdn缓存)、浏览器缓存,浏览器缓存也包含很多内容:http缓存、indexdb、cookie、localstorage等,我们只讨论http缓存。
http缓存
通过下图对http缓存有个整体认识:
http报文是浏览器和服务器间通信时发送及响应的数据块。浏览器向服务器请求数据,发送请求request报文;服务器向浏览器返回数据,返回响应response报文。而报文信息主要分为两部分:
包含属性的首部报头header,cookie,缓存信息等与缓存相关的规则信息,均包含在header中;
包含数据的主体部分body,这是http请求真正想要传输的部分。
可以看出,http缓存得以实现主要取决于header中的参数,我们通过分析header中关于缓存的参数,可以了解http缓存是怎么工作的。
http缓存主要分为两大类:强制缓存、对比缓存。
强制缓存
在没有缓存数据的情况下,浏览器向服务器请求数据时,服务器会将数据和缓存规则一并返回,缓存规则信息包含在响应header中;在缓存数据未失效的情况下,可以直接使用缓存数据,对于强制缓存来说,响应header中会有两个字段来标明失效规则(expires/cache-control)。
expires
expires值为服务端返回的到期时间,即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。不过expires是http1.0的东西,现在浏览器均默认使用http1.1(cache-control),所以它的作用基本忽略。
cache-control
cache-control常见的取值有private、public、no-cache、max-age,no-store,默认为private。
private:客户端可以缓存 public:客户端和代理服务器都可缓存 max-age=xxx:缓存的内容将在xxx秒后失效 no-cache:需要使用对比缓存来验证缓存数据 no-store:所有内容都不会缓存,强制缓存,对比缓存都不会触发
对比缓存
对比缓存,进行比较判断是否可以使用缓存。当浏览器第一次请求数据时,服务器会将缓存标识与数据一起返回给客户端,客户端将二者备份至缓存数据库中;再次请求数据时,客户端将备份的缓存标识发送给服务器,服务器根据缓存标识进行判断,成功则返回304状态码,通知客户端可以使用缓存数据,不成功则返回200状态码,重新获取数据。
对比缓存的header中主要有两种缓存标识,分别在请求header和响应header中。
last-modified / if-modified-since
last-modified(响应header中):服务器在响应请求时,告知浏览器资源的最后修改时间。 if-modified-since(请求header中):再次请求服务器时,通过此字段通知服务器上次请求时服务器返回的资源最后修改时间。 服务器收到请求后发现有头if-modified-since 则与被请求资源的最后修改时间进行比对,若资源的最后修改时间大于if-modified-since,则返回状态码200,重新返回资源;若资源的最后修改时间小于或等于if-modified-since,则响应状态码304,告知浏览器继续使用所保存的cache。
etag / if-none-match(优先级高于last-modified/if-modified-since)
etag(响应header中):服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。 if-none-match(请求header中):再次请求服务器时,通过此字段告知服务器浏览器缓存数据的唯一标识。 服务器收到请求后发现有if-none-match,则与被请求资源的唯一标识进行比对,不同,返回状态码200,重新返回资源;相同,返回状态码304,告知浏览器继续使用所保存的cache。