当前位置: 首页 > 科技观察

从未如此简单:5分钟搞懂HTTP缓存机制

时间:2023-03-18 11:04:13 科技观察

什么是HTTP缓存HTTP缓存可以说是HTTP性能优化中一种简单高效的优化方式。缓存是一种保存资源副本的方式,直接使用这种副本技术,当web缓存发现请求的资源已经被存储时,会拦截请求并返回一份资源的副本,而不用去源服务器重新下载.优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,节省网络流量,并且因为缓存文件可以重用,降低网络负载,提高客户端响应。因此,学习使用HTTP缓存是很有必要的。在这里,我将系统地向大家介绍一下HTTP缓存机制,希望能帮助大家正确理解HTTP缓存。缓存策略在讲解不同的HTTP缓存策略之前,我们需要知道用户刷新/访问行为的手段分为三类:在URI输入框回车/通过书签访问F5/点击工具栏的刷新按钮/restart右键菜单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内再次请求这个days的数据会直接获取缓存数据库中的数据,直接使用。然后我们再次尝试访问该资源,会出现如下响应:可以看到HTTP状态码为200,Size字段显示:diskcache,说明浏览器确实经过了强制缓存,没有与浏览器交互的时间更长。正如我们上面所说,不同的访问/刷新方式会导致浏览器使用不同的缓存策略。要使浏览器使用强制缓存,对请求方法有要求:在URI输入字段中输入并按Enter/通过书签访问。比较缓存当浏览器已经缓存了数据时,使用比较缓存请求数据的过程如下。可能有同学会问,基于比较缓存的过程,不管用不使用缓存,都要向服务器发送请求,为什么要用缓存呢?我们现在来讨论这个问题。比较缓存,顾名思义,就是需要通过比较来判断缓存是否可以使用。当浏览器第一次请求数据时,服务器会将缓存标识和数据返回给浏览器,浏览器将它们备份到缓存数据库中。当浏览器再次请求数据时,浏览器将备份的缓存ID发送给服务器,服务器根据缓存ID进行判断。判断成功后,返回304状态码,通知客户端比较成功,可以使用缓存数据。比如第一次访问:第二次访问:用于比较缓存,响应头中会有两个字段表示规则Last-Modified/If-Modified-Since当服务器响应请求时,会告诉browsera告诉浏览器资源的最后修改时间:Last-Modified。稍后浏览器再次请求时,会带上一个header:If-Modified-Since。这个值是服务器上次给出的Last-Modified时间。服务器会比较资源当前的最后修改时间,如果大于If-Modified-Since,则说明资源已经被修改,浏览器不能再使用缓存,否则浏览器可以继续使用缓存并返回304状态代码。Etag/If-None-Match(优先级高于Last-Modified/If-Modified-Since)当服务器响应请求时,通过Etag头(即生成规则由服务器决定),浏览器再次请求时,会带上一个headerIf-None-Match。这个值是服务器上次给的Etag的值。服务器比较资源当前的Etag是否与If-None-Match一致。如果不一致,说明资源修改后,浏览器不能再使用缓存,否则浏览器可以继续使用缓存,返回304状态码。我们来看一个例子:第一个请求,服务器的响应头包含:第二个请求,浏览器的请求头总结我们来看一个HTTP缓存的大致流程图:HTTP缓存主要分为强制缓存和对比缓存。cachedHTTP相关headersCache-Control,Exipres(HTTP1.0),浏览器直接读取本地缓存,不再与服务器交互,状态码为200。与缓存的HTTP相关头Last-Modified/If-Modified-Since、Etag/If-None-Match(优先级高于Last-Modified/If-Modified-Since)相比,每次请求都需要让服务器判断资源是否匹配isUpdate判断浏览器是否使用了缓存,如果使用则返回304,否则重新完成响应。