关于http缓存的文章我们或许已经看到了很多,但有几点你可能从来不知道:
-
- 你看到的大多数缓存决策图是错的;
-
- 强缓存和协商缓存的概念可能不存在;
-
- 浏览器默认的缓存策略是什么。
你看到的大多数缓存决策图是错的
上图是我在掘金搜到的一篇关于http缓存讲解的文章中截取的。该图的主要目的是讲解浏览器对缓存的处理流程。在图中红框圈起来的地方会很容易的给人以误解,就是当ETag存在的情况下不会去检查Last-Modified, 且if-None-Match和if-Modified-Since请求头只发送一个就好了。
但实际情况却是如果上一次请求有ETag,则在浏览器端的缓存过期后发起的请求就会带上if-None-Match请求头,如果上一次请求有Last-modified,浏览器也会带上,他们两个的判断不存在一个先后的关系。简单来说就是有就带上,没有就不带。
下面附上一张相对合理的浏览器的缓存策略决策图。
强缓存和协商缓存的概念可能不存在
在许多关于http缓存讲解的文章中我们都会看到将缓存分为强缓存和协商缓存两种。但是我在查阅MDN(HTTP 缓存 - HTTP | MDN (mozilla.org)关于缓存的文章中以及rfc关于缓存的规范中都没有发现关于强缓存和协商缓存的概念,类似的概念只存在于中文互联网中,且最早应该是出现在2012年左右。而在2012年以前的文章对缓存的介绍中大多提到的是浏览器强制缓存和缓存协商过程类似的名词,后来就慢慢变成了强缓存和协商缓存的概念。
浏览器默认的缓存策略又是什么呢
我们都知道浏览器端的缓存都有一个过期时间,具体的过期时间取决于http的cach-control和Expires响应头。比如Cache-control: max-age=N的头,相应的缓存的寿命就是N
。通常情况下,对于不含这个属性的请求则会去查看是否包含Expires属性,通过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。但如果响应头里既没有Cache-control又没有Expires的情况下浏览器还会对该htpp响应的内容进行缓存吗?,如果会的话过期时间又是多久呢?
答案是:如果max-age和Expires属性都没有,浏览器就会找响应头里的Last-Modified字段。如果有,缓存的寿命就等于头里面Date的值减去Last-Modified的值除以10,Date值代约等于你收到响应的时间。 但是如果响应头里连Last-Modified字段也不存在呢,浏览器会如何缓存?
答案是:如果既没有Cache-control也没有Expires,也没有Last-Modified字段,也不存在ETag字段,浏览器就不会对该请求进行缓存。对浏览器来说每次都是发起一个新的请求。
以上如有问题,欢迎大家指正。