详解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状态码时,浏览器直接使用缓存。

本文分享自微信公众号 - 编程沉思录(code-thinker)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-02-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 缓存的正确使用方式,你都会了吗?

    首先,缓存由于其适应高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。

    黄泽杰
  • 为什么我们做分布式使用 Redis?

    绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 Set Value 和 Get Value 两个操作,对 Redis 整体缺乏一个认知。这里...

    黄泽杰
  • 缓存与数据库一致性问题深度剖析

    当我们在做数据库与缓存数据同步时,究竟更新缓存,还是删除缓存,究竟是先操作数据库,还是先操作缓存?本文带大家深度分析数据库与缓存的双写问题,以供大家参考。

    黄泽杰
  • Web缓存 - HTTP协议缓存

    Web缓存一般分为浏览器缓存、代理服务器缓存以及网关缓存,本文主要讲的是 浏览器缓存,其它两种缓存大家自行去了解下。

    laixiangran
  • 【玩转腾讯云】秒杀系统实战 | 缓存与数据库双写一致性深度分析

            ———— 已经拥有黑眼圈,但还没学会小猪老师时间管理学的蛮三刀同学

    后端技术漫谈
  • 秒杀系统实战(四)| 缓存与数据库双写问题的争议

    在秒杀实际的业务中,一定有很多需要做缓存的场景,比如售卖的商品,包括名称,详情等。访问量很大的数据,可以算是“热点”数据了,尤其是一些读取量远大于写入量的数据,...

    Rude3Knife的公众号
  • 面对海量请求,缓存设计还应该考虑哪些问题?

    陈树义
  • 缓存的正确使用方式,你都会了吗?

    首先,缓存由于其适应高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。

    黄泽杰
  • 面对海量请求,缓存设计还应该考虑哪些问题?

    从第一个缓存框架 Memcached 诞生以来,缓存就广泛地存在于互联网应用中。如果你的应用流量很小,那么使用缓存可能并不需要做多余的考虑。但如果你的应用流量达...

    lyb-geek
  • 分布式之数据库和缓存双写一致性方案解析

    首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。

    lyb-geek

扫码关注云+社区

领取腾讯云代金券