当前位置: 首页 > 后端技术 > Python

5分钟看懂系列:HTTP缓存机制详解

时间:2023-03-25 21:29:15 Python

什么是HTTP缓存?复制技术,当web缓存发现请求的资源已经被存储时,会拦截请求并返回一份资源的副本,而无需再去源服务器下载。优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,节省网络流量,并且因为缓存文件可以重用,降低网络负载,提高客户端响应。因此,学习如何使用HTTP缓存是很有必要的。这里,我将系统地向大家介绍一下HTTP缓存机制,希望能帮助大家正确理解HTTP缓存。缓存策略在讲解HTTP的不同缓存策略之前,我们需要知道用户刷新/访问行为的手段分为三类:在URI输入框输入并回车/通过书签访问F5/点击刷新按钮工具栏/重启右键菜单LoadingCtl+F5(完全不使用HTTP缓存)和不同的刷新方式会导致浏览器使用不同的缓存策略。下面我们来分析一下,HTTP缓存主要是通过请求和响应头中对应的Header信息来控制的。缓存策略。响应标头中的相关字段是Expires、Cache-Control、Last-Modified和Etag。HTTP缓存有很多种,根据是否需要向服务器重新发起请求可以分为两种:强制缓存和对比缓存。假设浏览器有缓存数据库进行本地缓存,我们先来看浏览器对资源的请求:强制缓存:当浏览器已经缓存数据时,使用强制缓存请求数据的过程如下:从流程图可以看出,强制缓存在缓存数据没有失效的情况下,可以直接使用缓存数据。需要重新请求服务器,那么浏览器如何判断缓存的数据是否失效呢?对于强制缓存,响应头中会有两个字段表示过期规则(Expires/Cache-Control):Expires:Expires是HTTP1.0的产物,现在默认浏览器默认使用HTTP1.1,所以它的作用基本被忽略。但是许多网站仍然与它兼容。它的值为服务器返回的过期时间,即下次请求时,请求时间小于服务器返回的过期时间,直接使用缓存的数据。但是有一个问题就是过期时间是由服务器产生的。如果客户端时间与服务器时间不一致,这将导致缓存命中错误。在HTTP1.1版本中,Expires被Cache-Control取代。Cache-Control:Cache-Control是最重要的规则。常用值有private、public、no-cache、max-age、no-store,默认为private。(1)max-age:用于设置资源(representations)可以缓存多长时间,以秒为单位;(2)s-maxage:与max-age相同,但仅用于代理服务器缓存;(3)public:表示响应可以被任何缓存区缓存;(4)private:只能针对个人用户,不能被代理服务器缓存;(5)no-cache:强制客户端直接向服务器发送请求,也就是说每次请求都必须发送给服务器。服务器收到请求,然后判断资源是否发生变化,如果是则返回新的内容,否则返回304,不变。这很容易产生误导,让人误以为响应没有被缓存。实际上,Cache-Control:no-cache会被缓存,但是每次向客户端(浏览器)提供响应数据时,缓存都必须评估缓存的响应对服务器的有效性。(6)no-store:禁止所有缓存(意思是响应不缓存)。例如:比如一个资源响应头是:cache-control:public,max-age=31536000,那么这个资源会被缓存31536000秒(365天),并请求这个365天内再次获取数据,会直接获取缓存数据库中的数据,直接使用。然后我们再次尝试访问该资源,会出现如下响应:可以看到HTTP状态码为200,Size字段显示:diskcache,说明HTTP响应报文的大小为0。与浏览器。正如我们上面所说,不同的访问/刷新方式会导致浏览器使用不同的缓存策略。要求浏览器对请求方式使用强制缓存:在URI输入框输入回车/通过书签比对访问缓存:当浏览器已经缓存数据时,使用比对缓存请求数据的过程如下:有同学可能会问,根据比较缓存的过程,不管有没有使用缓存,一个请求都需要发送到服务器,那你还用缓存做什么?我们现在来讨论这个问题。比较缓存,顾名思义,就是需要通过比较来判断缓存是否可以使用。当浏览器第一次请求数据时,服务器会将缓存标识和数据返回给浏览器,浏览器将它们备份到缓存数据库中。当浏览器再次请求数据时,浏览器将备份的缓存ID发送给服务器,服务器根据缓存ID进行判断。判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。例如:Firstvisit:Secondvisit:与缓存相比,响应头中会有两个字段表示规则Last-Modified/If-Modified-Since当服务器响应请求时,会通过Last-ModifiedHTTPheader服务器资源的最后修改时间,浏览器在本地缓存该资源,以后再请求时,会带上一个HTTPheaderIf-Modified-Since。这个值是服务器上次给的Last-Modified时间,服务器会把浏览器传过来的时间和资源的最后修改时间进行比较。如果大于If-Modified-Since,说明资源被修改,浏览器不能再使用缓存,服务器会重新创建一个完整的资源浏览器,否则浏览器可以继续使用缓存和返回304状态码Etag/If-None-Match(优先级高于Last-Modified/If-Modified-Since)。服务器响应请求时,通过EtagHTTP头告诉浏览器当前资源在服务器的Uniqueidentifier中(生成规则由服务器决定)。浏览器再次请求时,会带上一个headerIf-None-Match。这个值是服务器上次给的Etag的值。服务端比较资源当前的Etag是否和If-None-Match一致,如果不一致,说明资源被修改,浏览器不能再使用缓存,否则浏览器可以继续使用缓存并返回304状态码。值得注意的是Etag的校验优先级高于Last-Modified看一个例子:第一个请求,服务器的响应头包含第二个请求,浏览器的请求头汇总我们来看一个大概的流程图HTTP缓存:HTTP缓存主要分为强制缓存和对比缓存mandatory缓存的HTTP相关的headersCache-Control,Exipres(HTTP1.0),浏览器直接读取本地缓存,不会再与服务器进行交互,状态码为200。与缓存的HTTP相关头Last-Modified/If-Modified-Since、Etag/If-None-Match(优先级高于Last-Modified/If-Modified-Since)相比,每次请求都需要让服务器判断资源是否匹配isUpdate判断浏览器是否使用了缓存,如果使用则返回304,否则重新完成响应。关于我如果文章对您有所帮助,您可以收藏转发,这将是对我莫大的鼓励!另外,大家可以关注我公众号【码农富哥】(coder2025),我会持续输出原创算法和计算机基础文章!