详解HTTP缓存

HTTP缓存是一项重要且常见的web性能优化手段。当通过浏览器发送HTTP请求时,如果浏览器本地有所要请求的文档副本,那么浏览器可以直接从本地存储中读取该文档,而不用到服务器上下载该文档。使用HTTP缓存具有如下几点好处:

减少冗余的数据传输

缓解网络瓶颈

减缓服务器压力

降低请求时延

既然HTTP缓存有诸多好处,那么其背后的原理是怎样的呢?接下来将为大家揭开HTTP缓存的神秘面纱。

一、第一次发送HTTP请求

为了方便理解,我们可以简单地认为浏览器存在一个缓存数据库,用于缓存数据。在浏览器第一次请求数据时,此时浏览器缓存中没有对应的缓存数据,需要请求服务器,服务器返回后,根据服务器返回的缓存规则,将数据存储至缓存数据库中。其大致流程如下图:

由上图可知浏览器是根据一定的缓存规则对数据进行缓存的,那么具体是怎样的缓存规则呢?HTTP缓存有多种规则,根据是否需要重新向服务器发起请求来分类,可分为两大类:强制缓存和对比缓存。

二、强制缓存

强制缓存是指如果浏览器中存在缓存数据并且数据没有过期,那么直接从缓存中读取数据,而无需向服务器发起询问。以下是强制缓存发生的时序图:

从上图可知,当使用强制缓存时,浏览器无需询问服务器就能判断数据是否过期,那么浏览器是根据什么来判断的呢?这就不得不提到跟强制缓存相关的2个HTTP响应头了,分别是:Expires和Cache-Control。

Expires的值是服务端设置的资源过期时间,浏览器就是根据这个过期时间跟发起HTTP请求的当下时间作比较,如果当下时间早于过期时间,则直接使用该缓存资源。但是因为服务器设置的这个过期时间是绝对时间,而浏览器跟服务器的时间可能不一致,因此可能会产生误差,所以现在Expires响应头已经用的比较少了。

Cache-Control的值有如下几个:private、public、no-cache、max-age,no-store,默认为private。

private 表示客户端可以缓存

public 表示客户端和代理服务器都可缓存

max-age=xxx 表示缓存的内容将在 xxx 秒后失效

no-cache 表示需要使用对比缓存来验证缓存数据(后面介绍)

no-store 表示所有内容都不会缓存,强制缓存,对比缓存都不会触发

由此可见Cache-Control的功能更加强大,且过期时间是相对时间,所以现在用的比较多的还是Cache-Control。

三、对比缓存

对比缓存是指如果浏览器中存在缓存数据,则必须向服务器发起请求以询问该数据是否过期,从而决定是否使用本地缓存。以下是对比缓存的时序图:

对比缓存指的是每次发送HTTP请求时,如果本地有缓存数据,那么浏览器也需要发送额外的HTTP请求与服务器进行对比,以确定本地数据是否过期。

对于对比缓存来说,缓存标识的传递是我们需要着重理解的,它在请求头和响应头间进行传递,服务端就是根据该缓存标识来判断资源是否过期的。一共可分为以下两种标识传递,接下来将分开介绍。

第一种是Last-Modified响应头和If-Modified-Since请求头。

Last-Modified的值表示的是资源的最后修改时间,在浏览器第一次发起HTTP请求时,服务器会返回该响应头。

浏览器在下次发起HTTP请求时,会带上If-Modified-Since请求头,其值就是第一次发送HTTP请求时,服务器设置在Last-Modified响应头中的值。

服务器收到请求后如果发现有请求头If-Modified-Since则与被请求资源的最后修改时间进行比对。若资源的最后修改时间大于If-Modified-Since,说明资源有被改动过,则响应完整的资源内容,返回状态码为200;若资源的最后修改时间小于或等于If-Modified-Since,说明资源未被修改,则响应HTTP状态码为304,告知浏览器继续使用所保存的缓存。

第二种是Etag响应头和If-None-Match请求头。

Etag响应头的值为当前资源在服务器的唯一标识(生成规则由服务器决定),在浏览器第一次发起HTTP请求时,服务器会返回该响应头。

当浏览器下次向服务端请求该资源时,会带上If-None-Match请求头,其值为第一次请求时服务器返回的Etag响应头的值。

服务器收到请求后如果发现有请求头头If-None-Match则与被请求资源的唯一标识进行比对。如果不同,说明资源有被改动过,则响应完整的资源内容,返回状态码为200;如果相同,说明资源未被修改过,则响应HTTP304,告知浏览器继续使用所保存的缓存。

四、总结

对于强制缓存,服务器通知浏览器一个缓存时间,在缓存时间内,下次请求,直接用缓存,不在缓存时间内,执行比较缓存策略。

对于比较缓存,将缓存信息中的Etag或者Last-Modified通过请求发送给服务器,由服务器校验,返回304状态码时,浏览器直接使用缓存。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180205G1BY0400?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券