掌握缓存,不再让你蓝瘦香菇 —— 祝各位程序员节日快乐!

本文内容概要:

1 Web缓存是什么?为什么要使用它?

2 Web缓存的类型

3 浏览器缓存的基本知识

3.1 Expires

3.2 Last-modified

3.3 Cache-Control

3.4 ETag

4 浏览器缓存机制

4.1 强缓存应用

4.2 协商缓存应用

4.3 强缓存与协商缓存的区别

5 浏览器缓存的流程

6 浏览器缓存的优化

1 Web缓存是什么?为什么要使用它

Web缓存是介于服务器与客户端之间。服务器可能是源服务器(因为中间可能会有代理服务器),就是网站资源所在的服务器。客户端指的是我们的浏览器。Web缓存就是在服务器和客户端之间搞监督,监督请求,并把请求的结果传给浏览器显示出来,另外存储一份(我们称为副本,也就是缓存)。然后,我们下次请求相同的URL路径,直接请求保存的副本(缓存),而不是再次向源服务器获取数据。

缓存的好处:

优秀的缓存策略可以缩短网页请求资源的距离,从而减少延迟时间,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。

Tips:带宽是指在单位时间(一般指的是1秒钟)内能传输的数据量。网络和高速公路类似,带宽越大,就类似高速公路的车道越多,其同行能力越强。

2 Web缓存的类型

2.1 浏览器缓存

通过使用HTTP协议与服务器交互的时候,浏览器就会根据一套与服务器约定的规则进行缓存工作。

2.2 代理服务器缓存

代理服务器是浏览器和源服务器之间的中间服务器,浏览器先向这个中间服务器发起Web请求,经过处理后(比如权限验证,缓存匹配等),再将请求转发到源服务器。

2.3 数据库缓存

当Web应用逻辑较为复杂,频繁进行数据库查询,很容易导致数据库不堪重荷。为了提高查询的性能,将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返回,提高响应效率。

2.4 应用层缓存

通过代码逻辑,把之前请求过的数据缓存起来,再次需要数据时通过逻辑上的处理选择可用的缓存的数据。

今天我们要给大家讲解的是浏览器缓存,先来看看浏览器缓存的基本知识。

3 浏览器缓存的基本知识

浏览器的缓存状态是由HTTP header决定的,header的参数有四种:Expires、Last-modified、Cache-Control、ETag;

3.1 Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。

3.2 Last-modified

服务器端文件的最后修改时间,需要和Cache-Control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。

3.3 Cache-Control

max-age(单位为s):指定设置缓存最大的有效时间,定义的是时间长短。比如Cache-Control:max-age=200表示文件在浏览器应该缓存且有效时长是200秒(从发出请求算起)。在接下来200秒内,如果有再次请求这个资源,浏览器不会向服务器发出HTTP请求,而是直接使用浏览器缓存下来的文件。

3.4 ETag

ETag和Last-Modified也是一样的,是对文件进行标识的字段。不同的是,ETag是根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。在向服务器查询文件是否有更新时,浏览器通过If-None-Match字段把特征字串(hash字符串)发送给服务器,由服务器和文件最新特征字串进行匹配,来判断文件是否有更新。没有更新则返回304,有更新则返回200。ETag和Last-Modified可根据需求使用一个或两个同时使用。两个同时使用时,只要满足基中一个条件,就认为文件没有更新。

3.5 四种参数的对比

4 浏览器缓存机制

4.1 强缓存应用

1 浏览器第一次向服务器请求一个资源时,服务器返回这个资源的同时,在respone的header加上Expires的header;

2 浏览器在接收到这个资源后,会把这个资源连同所有response header一起缓存下来(所以符合条件的缓存请求返回的header并不是来自服务器,而是来自之前缓存的header);

3 浏览器再请求这个资源时,先从缓存中寻找,找到这个资源后,拿出它的Expires跟当前的请求时间比较,如果请求时间在Expires指定的时间之前,就符合缓存要求,否则向服务器请求资源;

4 如果没有符合缓存的要求,浏览器直接从服务器加载资源时,Expires Header在重新加载的时候会被更新;

Expires的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大(比如:客户端的时间是2016.07.01 21:05.07,而服务器的时间是2016.07.12 12:15.07,缓存过期的时间是2016.07.23 20:05.07,这样会产生延迟过期),那么误差就很大,另外一个问题是,你很容易忘记给某内容设置了一个特定时间,如果返回内容的时候没有更新这个过期时间(Expires),则每个请求都是访问到服务器,反而增加了负载和响应时间。所以在HTTP 1.1版开始,使用Cache-Control: max-age来进行替代。

注意:

max-age是根据它第一次的请求时间和Cache-Control设定的有效期,计算出一个资源过期时间,再拿这个过期时间跟当前的请求时间比较,如果请求时间在过期时间之前,就符合缓存要求,否则就不行。

Expires和Cache-Control同时存在时,Cache-Control优先级高于Expires;

强缓存通常都是针对静态资源使用,动态资源需要慎用,除了服务端页面可以看作动态资源外,那些引用静态资源的html也可以看作是动态资源,如果这种html也被缓存,当这些html更新之后,可能就没有机制能够通知浏览器这些html有更新,尤其是前后端分离的应用里,页面都是纯html页面,每个访问地址可能都是直接访问html页面,这些页面通常不加强缓存,以保证浏览器访问这些页面时始终请求服务器最新的资源。

4.2 协商缓存应用

1 浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上Last-Modified的header,这个header表示这个资源在服务器上的最后修改时间;

2 浏览器再次向服务器请求这个资源时,在request的header上加上If-Modified-Since的header,这个header的值就是上一次请求时返回的Last-Modified的值;

3 服务器再次收到资源请求时,根据浏览器传过来If-Modified-Since和资源在服务器上的最后修改时间判断资源是否有变化,如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。当服务器返回304 Not Modified的响应时,response header中不会再添加Last-Modified的header,因为既然资源没有变化,那么Last-Modified也就不会改变,这是服务器返回304时的response header;

4 浏览器收到304的响应后,就会从缓存中加载资源;

5 如果不符合协商缓存要求,浏览器直接从服务器加载资源时,Last-Modified Header在重新加载的时候会被更新,下次请求时,If-Modified-Since会启用上次返回的Last-Modified值。

Last-Modified和If-Modified-Since都是根据服务器时间返回的header,一般来说,在没有调整服务器时间和篡改客户端缓存的情况下,这两个header配合起来管理协商缓存是非常可靠的,但是有时候也会服务器上资源其实有变化,但是最后修改时间却没有变化的情况,而这种问题又很不容易被定位出来,而当这种情况出现的时候,就会影响协商缓存的可靠性。所以就有了另外一对header来管理协商缓存,这对header就是ETag和If-None-Match。

1 浏览器第一次向服务器请求一个资源,服务器在返回这个资源的同时,在respone的header加上ETag的header,这个header是服务器根据当前请求的资源生成的一个唯一标识,这个唯一标识是一个字符串,只要资源有变化这个串就不同,跟最后修改时间没有关系,所以能很好的补充Last-Modified的问题;

2 浏览器再次跟服务器请求这个资源时,在request的header上加上If-None-Match的header,这个header的值就是上一次请求时返回的ETag的值;

3 服务器再次收到资源请求时,根据浏览器传过来If-None-Match和然后再根据资源生成一个新的ETag,如果这两个值相同就说明资源没有变化,否则就是有变化;如果没有变化则返回304 Not Modified,但是不会返回资源内容;如果有变化,就正常返回资源内容。与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化;

4 浏览器收到304的响应后,就会从缓存中加载资源;

注意:

大部分Web服务器都默认开启协商缓存,而且是同时启用Last-Modified和If-Modified-Since、ETag和If-None-Match这也是为了处理Last-Modified不可靠的情况;

协商缓存需要配合强缓存使用,因为如果不启用强缓存的话,协商缓存根本没有意义;

4.3 强缓存与协商缓存的区别

共同点:如果符合条件,都是从客户端缓存中加载资源,而不是从服务器加载资源数据;

不同点:强缓存不发送请求到服务器,协商缓存会发送请求到服务器;

5 浏览器缓存的流程

6 浏览器缓存的优化

Last-Modified 需要向服务器发起查询请求,才能知道资源文件有没有更新。虽然服务器可能返回304告诉没有更新,但也还有一个请求的过程。对于移动网络,这个请求可能是比较耗时的。有一种说法叫“消灭304”,指的就是优化掉304的请求。

在实际应用中,为了解决 Cache-Control 缓存时长不好设置的问题,以及为了”消灭304“,Web前端采用的方式是:

1 在要缓存的资源文件名中加上文件MD5值字串,如 common.d5d02a02.css,同时设置 Cache-Control:max-age=31536000,也就是一年。在一年时间内,资源文件如果本地有缓存,就会使用缓存;也就不会有304的回包。

2 如果资源文件有修改,则更新文件内容,同时修改资源文件名,如 common.d5d02a02.cs,html页面就会引用新的资源文件名。

学习资料:

流云诸葛 张鑫旭-鑫空间-鑫生活 大额大额哼歌等日落的博客 腾讯全端 AlloyTeam 团队 Blog

原文发布于微信公众号 - HTML5学堂(h5course-com)

原文发表时间:2016-10-24

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信终端开发团队的专栏

IPv6 socket编程下--实现篇

本文将详细介绍IPv6 socket编程的具体实现,具体原理请点击:IPv6 socket编程上--原理篇 判断客户端可用的IP stack 原理大家都明白了,...

1.2K6
来自专栏程序人生

撰写合格的REST API

两周前因为公司一次裁人,好几个人的活都被按在了我头上,这其中的一大部分是一系列REST API,撰写者号称基本完成,我测试了一下,发现尽管从功能的角度来说,这些...

3175
来自专栏程序猿

Burp Suite第十八节: 使用Burp Suite测试Web Services服务

从这一节开始,我们进入了Burp的综合使用。通过一系列的使用场景的简单学习,逐渐熟悉Burp在渗透测试中,如何结合其他的工具,组合使用,提高工作...

3636
来自专栏WD学习记录

8-26 Android学习ing

在Android中,应用的响应性被活动管理器(Activity Manager)和窗口管理器(Window Manager)这两个系统服务所件事。当用户触发了输...

713
来自专栏WebHub

const web = HTTP1.1 => HTTP2.0

HTTP/2.0是下一代HTTP协议, 由IETF的 [httpbis] 工作小组进行开发。自1999年http1.1发布后的首个更新, HTTP 2.0在20...

832
来自专栏大魏分享(微信公众号:david-share)

技术派:谁说API网关只能集成REST APIs?

963
来自专栏大内老A

谈谈基于OAuth 2.0的第三方认证 [上篇]

对于目前大部分Web应用来说,用户认证基本上都由应用自身来完成。具体来说,Web应用利用自身存储的用户凭证(基本上是用户名/密码)与用户提供的凭证进行比较进而确...

18310
来自专栏扎心了老铁

redis的发布订阅模式pubsub

前言 redis支持发布订阅模式,在这个实现中,发送者(发送信息的客户端)不是将信息直接发送给特定的接收者(接收信息的客户端),而是将信息发送给频道(chann...

2807
来自专栏Java技术栈

干货 | 彻底弄懂 HTTP 缓存机制及原理

Http 缓存机制作为 web 性能优化的重要手段,对于从事 Web 开发的同学们来说,应该是知识体系库中的一个基础环节,同时对于有志成为前端架构师的同学来说是...

1463
来自专栏NetCore

Health Check in eShop -- 解析微软微服务架构Demo(五)

引言 What is the Health Check     Health Check(健康状态检查)不仅是对自己应用程序内部检测各个项目之间的健康状态(各项...

2015

扫码关注云+社区