HTTP缓存机制

372 阅读4分钟

⭐HTTP缓存机制有两种 强缓存,协商缓存。

第一次发起http请求

1、强缓存

是利用http的Header实现的:1、Expires 和1、Cache-Control

Expires和Cache-Control:max-age 都是用来判断在浏览器端的缓存是否超过生命期限,缓存只有在生命期限以内才算有效

区别:

1、Expires指定一个绝对的过期时间(类似于 2019.10.19 08:00:00),

客户端和服务器时间不同步导致Expires的配置出现问题而且很容易在配置后忘记具体的过期时间,导致过期来临出现浪涌现象;

2、max-age 指定的是从文档被访问后的存活时间,这个时间是个相对值(比如:3600s),相对的是文档第一次被请求时服务器记录的Request_time(请求时间)

如果没过期的话直接取出缓存中的数据,过期的话重新向服务器发起请求。

补上cache-control头的相关数据

2、协商缓存

利用http的Header实现的:1、Last-modified 2、Etag

通过last-modified (If-Modefied-Since)(比较时间)或者Etag(If-None-Match)(意思是Etag标识是否可以匹配到)来判断是否需要更新。

对比:

①强缓存优先于协商缓存。

②协商缓存的时候,Etag优先级比last-modefied高。

Etag的精确度比last-modefied高,不过在性能上Etag要逊色,毕竟last-modefied只需要记录时间,而Etag需要服务器通过算法来计算出一个hash值。

③强制缓存的时候,Cache-Control优先级高于Expires。

前者是http1.1 后者是http1.0

强制缓存有个毛病是它不关心资源有没有改变有没有更新是不是最新的,它只关心有没有过期。

关于Etag和last-modified的对比,本文在末尾将更详细讲解。

1、如果判断后结论是不需要更新,协商缓存就算是生效了。 服务端直接返回状态码304(表示你说请求的内容不需要服务端传送,直接使用本地缓存中的数据即可),使用缓存。

协商缓存生效

2、如果发现需要更新,协商缓存失效,服务端就会返回状态码200, 重新返回资源以及Etag缓存标识,再存入浏览器缓存中。

协商缓存失效

3、怎么知道判断浏览器默认是设置为强缓存还是协商缓存呢?

根据的是第一次请求时返回的响应头来决定的。

4、如果什么缓存策略都没设置,那么浏览器会怎么处理?

对于这种情况,浏览器会采用一个启发式的算法,通常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间。

5、css,js,html文件适合强缓存还是协商缓存?

css,js建议强缓存

html,图片文件 协商缓存

6、Etag和Last-modified

①Last-Modified :

1、如果本地打开缓存文件,即使没有对文件进行修改,但还是会造成 Last-Modified 被修改,服务端不能命中缓存导致发送相同的资源。

2、 Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源。

例子:(用0.5秒的时间修改文件,服务端认为时间对比之前的last-modified是一样的,没必要重新请求)


②ETag和If-None-Match

正是因为根据文件修改时间来决定是否缓存存在缺陷,所以以在 HTTP / 1.1 出现了 ETag 和If-None-Match,可以直接根据文件内容是否修改来决定缓存策略。

Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),

只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,

服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。

如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;

如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。

缓存机制图解

⭐ 总结

浏览器缓存机制的关键在于:

  浏览器每次发起请求,都会现在浏览器缓存里面找一找有没有与请求资源相对应的 缓存标识 和 资源。
  对于每次从服务端请求到的结果和缓存标识,都要存到浏览器缓存中。

想看更加详细的内容,推荐这篇:www.jianshu.com/p/54cc04190…