浏览器HTTP缓存的控制机制 --记录

153 阅读5分钟

1.浏览器的http请求

1.1浏览器的第一次请求

image.png

1.2浏览器的第二次请求

1638674442(1).png

2.浏览器的http缓存机制

2.1缓存类型

浏览器的http缓存类型分为强缓存和协商缓存两种,实际在加载页面时的简单流程如下: 1.浏览器先根据资源的http请求头来判断是否命中强缓存,如果命中强缓存,浏览器并不会将请求发送给服务器而是直接加载缓存中的资源; 2.如果没有命中强缓存,浏览器会将请求发送给服务器,由服务器来判断浏览器的本地缓存是否失效,如本地缓存可用,服务器就不会返回资源信息,而是让浏览器加载本地缓存中的资源; 3.如果未命中协商缓存,服务器就会返回资源请求中请求的资源给浏览器,浏览器会加载新的资源并更新本地的缓存。

2.2强缓存

当http请求命中强缓存时,请求并不会发送到服务器,而是直接加载本地的缓存资源。在浏览器的开发者工具可以看到请求的返回码是200,但是在size列会显示为(from cache)

image.png 强缓存利用的是http的返回头中的Expires或者Cache-Control两个字段控制的,用来表示资源的缓存时间。

2.2.1Expires

缓存过期时间,用来指定资源的到期时间,是服务器端具体的时间点,也就是说Expires=max-age+请求时间,需要和Last-modified结合使用。Expires是服务器响应消息头字段,它可以告诉浏览器在过期时间前浏览器可以直接从缓存中存取数据,无需再次请求。

2.2.2Cache-Control

Cache-Control是一个相对时间,例如Cache-Control:100,代表资源的有效时间是100s,由于Cache-Control是相对时间,且是与客户端的时间比较,所以就算服务端和客户端存在时间偏差也不会出现问题。

2.2.3两者比较

Cache-Control和Expires可以在服务端配置同时使用也可以只启用一个,当两个同时启用时Cache-Control的优先级更高。早期的http请求的缓存机制是使用Expires来判断资源是否过期的,但由于Expires是以服务端的时间来设置并且是个绝对时间,如客户端时间与服务端时间存在较大偏差或其他特殊情况时,会导致缓存混乱,所以发展出了Cache-Control;

2.3协商缓存

通俗来讲,协商缓存的含义是浏览器咨询服务器,浏览器缓存的资源是否从有更新,缓存资源是否还能使用。如果缓存资源没有更新还能继续使用,返回的响应头就不会有新资源,而浏览器则使用缓存的资源,此时的状态码就是304。如果缓存资源存在更新,服务器就会返回新资源给浏览器使用,浏览器使用新资源并更新缓存。

2.3.1与协商缓存相关的关键字段(早期的关键字段)

当浏览器第一次向服务器请求一个资源时,服务器返回的响应头会带有Last-Modify字段,该字段是一个标识了该资源的最后修改时间的时间。而后当浏览器再次请求该资源时,发送的请求头中会带上If-Modify-Since,该值为上一次返回头中带有的Last-Modify字段,服务器收到该字段后判断其是否能命中缓存。 如命中缓存,则返回304并且不会有新资源返回。由于对比的是服务端的时间,所以服务端与客户端即使存在时间差也不会影响结果。但有时候通过最后修改时间来判断是否过期也并不准确,于是出现了新的关键字段ETag/If-None-Match。

2.3.2与协商缓存相关的关键字段(现在常用的关键字段)

与以前的关键字段不同的地方在于,ETag/If-None-Match返回的是一个校验码,它能确保每一个资源都是唯一且最新的,每次资源的变化都会使ETag改变,ETag的值变更说明资源存在变化。与以前的关键字段相似的地方在于当浏览器再次请求同一资源时,会带上If-None-Match字段,其中保存的是上一次返回头中的ETag,服务器根据这个字段来判断缓存是否命中缓存。

1638681107(1).png

2.3.3 Last-Modify与ETag

Last-Modify存在了很长时间,但仍存在一些缺陷,ETag的出现是为了解决Last-Modify的缺陷可能导致的问题: a.Last-Modify标注的最后修改时间只能精确到秒,如果某些文件在一秒内改变了多次,就不能准确标注文件的修改时间。 b.有些文件可能会被定期生成,但内容却没有变化,这样Last-Modify虽然改变了,但是内容却没变,这就会导致原来缓存的资源无法使用。 c.可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情况。

另:ETag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识,能够更加准确的控制缓存(可以理解为git的版本),除此之外,Last-Modify与ETag是可以一起使用的,服务器会优先验证ETag,如果一样才会继续比对Last-Modify,最后决定是否返回304。

ETag的生成原理,附:

image.png