FED实验室 - 专注WEB端开发和用户体验

web缓存工作原理

JAVASCRIPT 煦涵 16782℃ 0评论

Web缓存的工作原理

所有的缓存都是基于一套规则来帮助他们决定什么时候使用缓存中的副本提供服务(假设有副本可用的情况下,未被销毁回收或者未被删除修改)。这些规则有的在协议中有定义(如HTTP协议1.0和1.1),有的则是由缓存的管理员设置(如DBA、浏览器的用户、代理服务器管理员或者应用开发者)。

一、浏览器端的缓存规则:

浏览器端的缓存规则是在HTTP协议头和HTML页面的Meta标签中定义的。他们分别从新鲜度和校验值两个维度来规定浏览器是否可以直接使用缓存中的副本,还是需要去源服务器获取更新的版本。

1.新鲜度(过期机制):

即缓存副本有效期

一个缓存副本必须满足以下条件,浏览器会认为它是有效的,足够新的:

a.含有完整的过期时间控制头信息(HTTP协议报头),并且仍在有效期内;

b.浏览器已经使用过这个缓存副本,并且在一个会话中已经检查过新鲜度;

满足以上两个情况的一种,浏览器会直接从缓存中获取副本并渲染。

2.校验值(验证机制):

服务器返回资源的时候有时在控制头信息带上这个资源的实体标签Etag(Entity Tag),它可以用来作为浏览器再次请求过程的校验标识。如过发现校验标识不匹配,说明资源已经被修改或过期,浏览器需要重新获取资源内容。

二、浏览器缓存的控制

1.使用HTML Meta 标签

Web开发者可以在HTML页面的<head>节点中加入<meta>标签,代码如下:

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

上述代码的作用是告诉浏览器当前页面不被缓存,每次访问都需要去服务器拉取。使用上很简单,但只有部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。

可以通过这个页面测试你的浏览器是否支持:Pragma No-Cache Test 。

2.使用缓存有关的HTTP消息报头

一个URI的完整HTTP协议交互过程是由HTTP请求和HTTP响应组成的。

在HTTP请求和响应的消息报头中,常见的与缓存有关的消息报头如下图:

o_http-header1

 

 

 

 

 

 

 

 

 

a)Cache-Control与Expires

Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是直接从浏览器缓存取数据,还是重新发送请求到服务器取数据。只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。

b)Last-Modified与ETag

1>Last-Modified:

在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记此文件在服务期端最后被修改的时间,格式类似这样:

Last-Modified: Fri, 12 May 2006 18:53:33 GMT

客户端第二次请求此URL时,根据 HTTP 协议的规定,浏览器会向服务器传送 If-Modified-Since 报头,询问该时间之后文件是否有被修改过:

If-Modified-Since: Fri, 12 May 2006 18:53:33 GMT

如果服务器端的资源没有变化,则自动返回 HTTP 304 (Not Changed.)状态码,内容为空,这样就节省了传输数据量。当服务器端代码发生改变或者重启服务器时,则重新发出资源,返回和第一次请求时类似。从而保证不向客户端重复发出资源,也保证当服务器有变化时,客户端能够得到最新的资源。

2>ETag

Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存. 典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:

ETag: "50b1c1d4f775c61:df3"

客户端的查询更新格式是这样的:

If-None-Match: W/"50b1c1d4f775c61:df3"

如果ETag没改变,则返回状态304,不返回内容,和Last-Modified一样。

3>Last-Modified已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要Etag呢?

HTTP1.1中ETag的出现主要是为了解决几个Last-Modified比较难解决的问题:

1>Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的新鲜度

2>如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存

3>有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

c)Last-Modified/ETag与Cache-Control/Expires

配置Last-Modified/ETag的情况下,浏览器再次访问统一URI的资源,还是会发送请求到服务器询问文件是否已经修改,如果没有,服务器会只发送一个304回给浏览器,告诉浏览器直接从自己本地的缓存读取数据;如果修改过那就整个数据重新发给浏览器;

Cache-Control/Expires则不同,如果检测到本地的缓存还是有效的时间范围内,浏览器直接使用本地副本,不会发送任何请求。两者一起使用时,Cache-Control/Expires的优先级要高于Last-Modified/ETag。即当本地副本根据Cache-Control/Expires发现还在有效期内时,则不会再次发送请求去服务器询问修改时间(Last-Modified)或实体标识(Etag)了。

一般情况下,使用Cache-Control/Expires会配合Last-Modified/ETag一起使用,因为即使服务器设置缓存时间, 当用户点击“刷新”按钮时,浏览器会忽略缓存继续向服务器发送请求,这时Last-Modified/ETag将能够很好利用304,从而减少响应开销。

 

三、用户操作与缓存

用户在使用浏览器的时候,会有各种操作,比如输入地址后回车,按F5刷新等,这些行为会对缓存有什么影响呢?

o_user-action2

 

 

 

 

从上图中我们可以看到,当用户在按F5进行刷新的时候,会忽略Expires/Cache-Control的设置,会再次发送请求去服务器请求,而Last-Modified/Etag还是有效的,服务器会根据情况判断返回304还是200;而当用户使用Ctrl+F5进行强制刷新的时候,只是所有的缓存机制都将失效,重新从服务器拉取资源。

四、使用缓存的好处:

1.减少网络带宽消耗

2.降低服务器压力

3.减少网络延迟,提高页面加载速度

 

2016-03-12补充,不错的总结:
腾讯AlloyTeam-浅谈Web缓存

下面是「FED实验室」的微信公众号二维码,欢迎扫描关注:

FED实验室

行文不易,如有帮助,欢迎打赏!

赞赏支持or喜欢 (0)or分享 (0)
捐赠共勉
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(3)个小伙伴在吐槽
  1. Hello blogger. I like your weblog about Tales from abroad » Blog Archive » Rafting. I was wondering, i am planning to make a weblog for myself. I want to use wordpress like you. Exactly where did you get your template? In the event you post your answer here below, i will read this inside the next few day’s. Thanks bbw webcamsex
    • The template by myself.
      Benjamin2014-07-16 00:23 回复
  2. Hey very nice blog!!