最近在对CDN进行优化,对浏览器缓存深入研究了一下,记录一下,方便后来者

画了一个草图:

每个状态的详细说明如下:

1、Last-Modified

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

Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT

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

If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT

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

注:如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求

2、Etag工作原理

HTTP协议规格说明定义ETag为“被请求变量的实体标记”(参见14.19)。简单点即服务器响应时给请求URL标记,并在HTTP响应头中将其传送到客户端,类似服务器端返回的格式:

Etag:“5d8c72a5edda8d6a:3239″

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

If-None-Match:“5d8c72a5edda8d6a:3239″

如果ETag没改变,则返回状态304。

即:在客户端发出请求后,HttpReponse Header中包含Etag:“5d8c72a5edda8d6a:3239″

标识,等于告诉Client端,你拿到的这个的资源有表示ID:5d8c72a5edda8d6a:3239。当下次需要发Request索要同一个URI的时候,浏览器同时发出一个If-None-Match报头(Http RequestHeader)此时包头中信息包含上次访问得到的Etag:“5d8c72a5edda8d6a:3239″标识。

If-None-Match:“5d8c72a5edda8d6a:3239“

,这样,Client端等于Cache了两份,服务器端就会比对2者的etag。如果If-None-Match为False,不返回200,返回304(Not Modified) Response。

3、Expires

给出的日期/时间后,被响应认为是过时。如Expires:Thu, 02 Apr 2009 05:14:08 GMT

需和Last-Modified结合使用。用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端.当缓存中数据失效或过期,才决定从服务器更新数据。

4、Last-Modified和Expires

Last-Modified标识能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而且要和Expires一起用。而Expires标识却使得浏览器干脆连HTTP请求都不用发,比如当用户F5或者点击Refresh按钮的时候就算对于有Expires的URI,一样也会发一个HTTP请求出去,所以,Last-Modified还是要用的,而且要和Expires一起用。

5、Etag和Expires

如果服务器端同时设置了Etag和Expires时,Etag原理同样,即与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的Last-Modified,Etag值完全一样;在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.

6、Last-Modified和Etag

分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败

分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样)

Last-Modified和ETags请求的http报头一起使用,服务器首先产生Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改,来决定文件是否继续缓存

过程如下:

1.客户端请求一个页面(A)。

2.服务器返回页面A,并在给A加上一个Last-Modified/ETag。

3.客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。

4.客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。

5.服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。

注:

1、Last-Modified和Etag头都是由WebServer发出的HttpReponse Header,WebServer应该同时支持这两种头。

2、WebServer发送完Last-Modified/Etag头给客户端后,客户端会缓存这些头;

3、客户端再次发起相同页面的请求时,将分别发送与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的Last-Modified,Etag值完全一样;

4、通过上述值到服务器端检查,判断文件是否继续缓存;

7、关于 Cache-Control: max-age=秒 和 Expires

Expires = 时间,HTTP 1.0 版本,缓存的载止时间,允许客户端在这个时间之前不去检查(发请求)
max-age = 秒,HTTP 1.1版本,资源在本地缓存多少秒。
如果max-age和Expires同时存在,则被Cache-Control的max-age覆盖。

Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。

Expires =max-age +   “每次下载时的当前的request时间”

所以一旦重新下载的页面后,expires就重新计算一次,但last-modified不会变化

每个状态的详细说明如下:

1、Last-Modified

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

Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT

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

If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT

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

注:如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求

2、Etag工作原理

HTTP协议规格说明定义ETag为“被请求变量的实体标记”(参见14.19)。简单点即服务器响应时给请求URL标记,并在HTTP响应头中将其传送到客户端,类似服务器端返回的格式:

Etag:“5d8c72a5edda8d6a:3239″

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

If-None-Match:“5d8c72a5edda8d6a:3239″

如果ETag没改变,则返回状态304。

即:在客户端发出请求后,HttpReponse Header中包含Etag:“5d8c72a5edda8d6a:3239″

标识,等于告诉Client端,你拿到的这个的资源有表示ID:5d8c72a5edda8d6a:3239。当下次需要发Request索要同一个URI的时候,浏览器同时发出一个If-None-Match报头(Http RequestHeader)此时包头中信息包含上次访问得到的Etag:“5d8c72a5edda8d6a:3239″标识。

If-None-Match:“5d8c72a5edda8d6a:3239“

,这样,Client端等于Cache了两份,服务器端就会比对2者的etag。如果If-None-Match为False,不返回200,返回304(Not Modified) Response。

3、Expires

给出的日期/时间后,被响应认为是过时。如Expires:Thu, 02 Apr 2009 05:14:08 GMT

需和Last-Modified结合使用。用于控制请求文件的有效时间,当请求数据在有效期内时客户端浏览器从缓存请求数据而不是服务器端.当缓存中数据失效或过期,才决定从服务器更新数据。

4、Last-Modified和Expires

Last-Modified标识能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而且要和Expires一起用。而Expires标识却使得浏览器干脆连HTTP请求都不用发,比如当用户F5或者点击Refresh按钮的时候就算对于有Expires的URI,一样也会发一个HTTP请求出去,所以,Last-Modified还是要用的,而且要和Expires一起用。

5、Etag和Expires

如果服务器端同时设置了Etag和Expires时,Etag原理同样,即与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的Last-Modified,Etag值完全一样;在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.

6、Last-Modified和Etag

分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败

分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样)

Last-Modified和ETags请求的http报头一起使用,服务器首先产生Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改,来决定文件是否继续缓存

过程如下:

1.客户端请求一个页面(A)。

2.服务器返回页面A,并在给A加上一个Last-Modified/ETag。

3.客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。

4.客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。

5.服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。

注:

1、Last-Modified和Etag头都是由WebServer发出的HttpReponse Header,WebServer应该同时支持这两种头。

2、WebServer发送完Last-Modified/Etag头给客户端后,客户端会缓存这些头;

3、客户端再次发起相同页面的请求时,将分别发送与Last-Modified/Etag对应的HttpRequestHeader:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和WebServer发出的Last-Modified,Etag值完全一样;

4、通过上述值到服务器端检查,判断文件是否继续缓存;

7、关于 Cache-Control: max-age=秒 和 Expires

Expires = 时间,HTTP 1.0 版本,缓存的载止时间,允许客户端在这个时间之前不去检查(发请求)
max-age = 秒,HTTP 1.1版本,资源在本地缓存多少秒。
如果max-age和Expires同时存在,则被Cache-Control的max-age覆盖。

Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。

Expires =max-age +   “每次下载时的当前的request时间”

所以一旦重新下载的页面后,expires就重新计算一次,但last-modified不会变化

原文地址:http://blog.csdn.net/eroswang/article/details/8302191

浏览器缓存详解:expires,cache-control,last-modified,etag详细说明的更多相关文章

  1. [转]浏览器缓存详解: expires, cache-control, last-modified, etag详细说明

    最近在对CDN进行优化,对浏览器缓存深入研究了一下,记录一下,方便后来者 画了一个草图: 每个状态的详细说明如下: 1.Last-Modified 在浏览器第一次请求某一个URL时,服务器端的返回状态 ...

  2. 【转载】浏览器缓存详解:expires cache-control last-modified

    https://www.cnblogs.com/caiyanhu/p/6931624.html 下面的内容展示了一个常见的 Response Headers,这些 Headers 要求客户端最多缓存 ...

  3. [面试专题]Web缓存详解

    Web缓存详解 标签(空格分隔): 缓存 缓存之于性能优化 请求更快:通过将内容缓存在本地浏览器或距离最近的缓存服务器(如CDN),在不影响网站交互的前提下可以大大加快网站加载速度. 降低服务器压力: ...

  4. 【转】MySQL查询缓存详解

    [转]MySQL查询缓存详解 转自:https://www.cnblogs.com/Alight/p/3981999.html 相关文章:http://www.zsythink.net/archive ...

  5. MySQL查询缓存详解(总结)

    MySQL查询缓存详解(总结) 一.总结 一句话总结: mysql查询缓存还是可以用用试一试,但是更推荐分布式,比如redis/memcache之流,将数据库中查询的数据和查询语句以键值对的方式存进分 ...

  6. redis使用及配置之缓存详解

    redis使用及配置之缓存详解 1.Redis的介绍 Redis是一个Key-Value存储系统.它支持存储的value类型有:string(字符串),list(链表), set(无序集合),zset ...

  7. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

  8. Hibernate缓存简介和对比、一级缓存、二级缓存详解

    一.hibernate缓存简介 缓存的范围分为3类:  1.事务范围(单Session即一级缓存)     事务范围的缓存只能被当前事务访问,每个事务都有各自的缓存,缓存内的数据通常采用相互关联的对象 ...

  9. Bitmap之内存缓存和磁盘缓存详解

    原文首发于微信公众号:躬行之(jzman-blog) Android 中缓存的使用比较普遍,使用相应的缓存策略可以减少流量的消耗,也可以在一定程度上提高应用的性能,如加载网络图片的情况,不应该每次都从 ...

随机推荐

  1. TCP/IP之大明内阁---协议的制定

    个人感言:真正的知识是深入浅出的,码农翻身" 公共号将苦涩难懂的计算机知识,用形象有趣的生活中实例呈现给我们,让我们更好地理解.感谢"码农翻身" 公共号,感谢你们的成果, ...

  2. AngularJS-chapter1-2-四大特性

    4大特性 MVC MVC实例  数据模型,控制器,视图 HelloAngular_MVC.html 图中的 ng-controller="HelloAngular"  定义了Hel ...

  3. Android四大组件及activity的四大启动模式

    Android四大组件 1. 广播接收者的两种类型: (1)系统广播接收者,就是继承BroadcastReceiver这个类,然后还要在清单文件中注册,注册之后给他一个action.当系统发生了这个a ...

  4. 基于springmvc和restClient的rest服务的测试

    在开发中,不熟悉驱动驱动测试开发的coder往往喜欢将服务应用启动以后测试,对于GET请求可以直接在浏览器中输入URL就可以,参数非中文可以直接追加到URL后.但是,对于其他请求方式的测试必须借助相应 ...

  5. 获取iPhone 联系人列表,并且根据分析得到的姓名首字母进行排序

    获取手机联系人以iOS9为分界点,大家都知道到了iOS9很多方法都更新了,好多接口都弃用,被新的接口代替.这Demo种有新旧两个接口,使用前判断当前iOS版本. 下面是Demo连接地址:Github的 ...

  6. 在SQLSERVER中快速有条件删除海量数据技巧推荐

    解释: 如果你的硬盘空间小,并且不想设置数据库的日志为最小(因为希望其他正常的日志希望仍然记录),而且对速度要求比较高,并清除所有的数据建议你用turncate table1,因为truncate 是 ...

  7. 总结一些关于操作数据库是sql语句还是存储过程问题

    总结一些关于操作数据库是sql语句还是存储过程问题 程序中,你跟数据的交互,需要向数据库拿数据.更改数据库的数据等,这些操作,本身不是程序完成的,而是程序发命令给数据库去做的,不管是通过sql语句方式 ...

  8. htnl5中设置文本单行显示,超出部分打省略号,鼠标移到文本时alt出全部文本内容

    Html代码: 1.<span class="my-span" title="无数无数无数无数无数">机构</span> Css样式: ...

  9. OpenVZ VPS加速方案–Final Speed

    body,td { font-family: 微软雅黑; font-size: 10pt }   OpenVZ VPS加速方案–Final Speed OpenVZ VPS加速方案–Final Spe ...

  10. 去掉IE下input的叉号

    IE10下的Input Text和谷歌下面的 input search 一旦输入内容,会在最右端出现一个叉号,点击后,内容就会自动清空,看似方便,其实有些场景并不需要,需要写代码清除掉. 代码如下: ...