文档章节

影响Cache的几个HTTP头信息

十月初五的月亮
 十月初五的月亮
发布于 2016/07/16 11:25
字数 3115
阅读 3
收藏 0
点赞 0
评论 0

注:本篇是关于http头信息cache的一些说明,理论行较强,但是很有用,不管是开发还是运维都得了解,如果还没有研究到这一块的朋友看起来觉得会比较枯燥。

转载于:http://hi.baidu.com/feilala_fly/blog/item/29b9f200f26c5f03738b6521.html

Http的Cache机制总共有4个组成部分:

Cache-Control、Last-Modified(If-Modified-Since)、Etag(If-None-Match) 、Expires

服务器响应头:Last-Modified,Etag
浏览器请求头:If-Modified-Since,If-None-Match

服务器发出Etag,Last-Modified头后,下次浏览器再进行同样的请求,则会发出If-None-Match,If-

Modified-Since头,而后服务器根据这些信息来判断是否需要发送数据,如果没有更新,服务器就简单的

发送一个304状态告诉浏览器用缓存就OK了,不用下载数据了,从而节约了带宽。

Last-Modified / If-Modified-Since

Last-Modified是响应头,If-Modified-Since是请求头。Last-Modified把Web组件的最后修改时间告诉客

户端,客户端在下次请求此Web组件的时候,会把上次服务端响应的最后修改时间作为If-Modified-Since

的值发送给服务器,服务器可以通过这个值来判断是否需要重新发送,如果不需要,就简单的发送一个

304状态码,客户端将从缓存里直接读取所需的Web组件。如果有更新,返回HTTP 200和更新的页面内容,

并且携带新的”ETag”和”LastModified”。

    使用这个机制,能够避免重复发送文件给浏览器,不过仍然会产生一个HTTP请求。

ETag / If-None-Match

ETag是响应头,If-None-Match是请求头。Last-Modified / If-Modified-Since的主要缺点就是它只能精确到秒的级别,一旦在一秒的时间里出现了多次修改,那么Last-Modified / If-Modified-Since是无法体现的。相比较,ETag / If-None-Match没有使用时间作为判断标准,而是使用一个特征串。Etag把Web组件的特征串告诉客户端,客户端在下次请求此Web组件的时候,会把上次服务端响应的特征串作为If-None-Match的值发送给服务端,服务端可以通过这个值来判断是否需要从重新发送,如果不需要,就简单的发送一个304状态码,客户端将从缓存里直接读取所需的Web组件。因此,HTTP/1.1利用Entity Tag头提供了更加严格的验证。

 

当服务器发出响应的时候,可以通过两种方式来告诉客户端缓存请求:

第一种是Expires,比如:Expires: Sun, 16 Oct 2016 05:43:02 GMT在此日期之前,客户端都会认为缓存是有效的。

不过Expires有缺点,比如说,服务端和客户端的时间设置可能不同,这就会使缓存的失效可能并不能精确的按服务器的预期进行。

第二种是Cache-Control,比如:Cache-Control: max-age=3600

这里声明的是一个相对的秒数,表示从现在起,3600秒内缓存都是有效的,这样就避免了服务端和客户端时间不一致的问题。

但是Cache-Control是HTTP1.1才有的,不适用与HTTP1.0,而Expires既适用于HTTP1.0,也适用于HTTP1.1,所以说在大多数情况下同时发送这两个头会是一个更好的选择,当客户端两种头都能解析的时候,会优先使用Cache-Control基础知识

         1) 什么是”Last-Modified”? 

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

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

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

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

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

         2) 什么是”Etag”? 

         HTTP 协议规格说明定义ETag为“被请求变量的实体值” (参见 —— 章节 14.19)。 另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式: 

        ETag: "50b1c1d4f775c61:df3"

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

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

         如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。本人测试Etag主要在断点下载时比较有用。
        
       Last-Modified和Etags如何帮助提高性能?
         聪明的开发者会把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头都是由Web Server发出的Http Reponse Header,Web Server应该同时支持这两种头。
2、Web Server发送完Last-Modified/Etag头给客户端后,客户端会缓存这些头;
3、客户端再次发起相同页面的请求时,将分别发送与Last-Modified/Etag对应的Http Request Header:If-Modified-Since和If-None-Match。我们可以看到这两个Header的值和Web Server发出的Last-Modified,Etag值完全一样;
4、通过上述值到服务器端检查,判断文件是否继续缓存;

 

关于Etag和Last-Modified网上还有更精辟的解释

1、关于Last-Modified

 

HTTP的Response中还会有另外一个Header叫Last-Modified,比如

“Last-Modified: Thu, 06 Apr 2006 21:17:12 GMT”,

浏览器访问一个URI得到这样的Resposne之后,就知道这个资源最后一次的修改时间,下次需要再次获得这个资源的时候,会发一个Request给Server,不过这个Request中有一条

“If-Unmodified-Since: Thu, 06 Apr 2006 21:17:12 GMT”,

如果在Server端在这个日期之后对这个资源进行了修改,就会照常返回这个资源给Client端,但是如果没有修改,就会返回一个304 (Not Modified) Response而不返回资源,告诉Client端:“这个资源从上次给你之来从来没改过,你放心用你Cache中的好了。” 一个304 Response比一个静态资源通常小多了,这样就节省了网络带宽。

 

2、Last-Modified和Expires的区别

让我们回过头来比较一下Expires和Last-Modified这两个东西,似乎Last-Modified比不上Expires,因为虽然它能够节省一点带宽,但是还是逃不掉发一个HTTP请求出去,而Expires却使得浏览器干脆连HTTP请求都不用发,岂不痛快!那还要Last- Modified这个物体干什么?理想状况的确是这样,不过当用户在IE或者Firefox里面按F5或者点击Refresh按钮的时候(不是在URL栏里重新输入一遍URL然后回车),就算对于有Expires的URI,一样也会发一个HTTP请求出去,所以,Last-Modified还是要用的,而且要和Expires一起用。 

3、Etag

除了Last-Modified,HTTP Response中还可能有另外一个Header: ETag,使得Server上的静态资源有点“版本控制”的味道,假如HTTP Response中包含

ETag: "abcdefg1234:0001"

等于告诉Client端,你拿到的这个版本的资源有个ID,叫做abcdefg1234:0001,下次需要发Request索要同一个URI的时候,在Request里面加一条

If-None-Match: "abcdefg1234:0001"

好,Server 端做了一些修改,下次这个Client再来了一个请求,但是这时候资源已经改了,所以返回这个新资源,还有新的tag “ETag: "abcdefg4567:0001"”(这个etag我是胡写的),这样,Client端等于Cache了两份,在需要索要这个资源的时候,可以包含这样的Header: “If-None-Match: "abcdefg1234:0001" "abcdefg4567:0001"”,这样,即使Server端头脑发热,把这个资源Roll back回原来的版本,依然会返回304 (Not Modified) Response,因为它知道Client端Cache着以前的版本呢,这点功能是Last-Modifed/If-Not-Modified没法做到的。 

4、Etag的弊端

不过ETag/If-None-Match这点功能实在是个鸡肋,首先,Server端的资源不大可能Roll Back,更重要的是,有可能造成Client Performance下降。对于只有一个Server的网站,没什么问题,但是现在稍微上点规模的网站都需要Scale Out,也就是说需要前端一个Load Balancer,后面接多台Server来处理请求,俗称Cluster,既然是Cluster,那么每个请求到底返回什么结果应该和分配到哪个 Server无关,不过这个ETag可能就坏事了。假如用户的第一次请求分配给Server A,返回“ETag: "abcdefg1234:0001"”,但是第二次请求分配给了Server B,Server B上这个资源和Server A上的一模一样,但是计算出这个资源的ETag是"abcdefg1234:0002",这下麻烦了,虽然内容一样,但是ETag不匹配,还是浪费了带宽把资源发送了一遍,冤枉啊!而事实上,不同Server上的ETag很有可能不同,对于Apache,ETag的计算考虑了inode,对于 IIS,ETag考虑了metabase的修改版本,要保证不同server上的这些信息一致,有点小难。不过不是有Last-Modified/If- Not-Modified吗?Server端看到If-Modified-Since,对照一下时间对得上,不管If-None-Match,可以直接发回304(Not Modified)呀,很不幸,RFC2616对这种情况做了规定,如果既有If-None-Match又有If-Modified-Since,除非两者不冲突,不然不会返回304。

 

所以说ETag就是一个害人精,按照Yahoo的建议,别费劲想办法同步不同Server上的ETag了,干脆就把ETag删除得了(缺省,Apache和 IIS都是有ETag的),我Sniff了一下Yahoo的若干网页返回HTTP Response,的确没有ETag,人家的确是知行合一

对于Apache,在httpd.conf或者.htaccess中加一行就搞定了:

5、Apache中的Etag设置
补充:
Apache默认开启Etag,可以使用FileEtag来设置

FileETag none|INode|MTime|Size|All

从apache的实现中http_etag.c我们可以发现,Apache的Etag包括了Inode|Mtime|Size这些因素。

对于IIS 6,可就有点费劲了,首先,似乎没有办法通过Config来把ETag去掉,查了很多资料,问了很多人,似乎能够去掉ETag的办法只有写一个ISAPI Filter来弄,Sniff了一下Microsoft的几个网页的结果显示ETag都稳当当的存在,估计目前真的没有什么好方法。

只好退而取其次,保证不同Server上的ETag一致了。 IIS对Etag的计算算法是ETag = {Filetimestamp:ChangeNumber}, Filetimestamp保持一致没什么问题,ChangeNumber是metabase的change number,就有点难保证Cluster中每个Server都一样了,所以,干脆就把它设成固定值好了,这个连接告诉我们该怎么办,很可惜,没有找到彻底删除ETags的配置。

当然转载于此方便以后自己查阅!!!!

本文转载自:http://tech110.blog.51cto.com/438717/549764

共有 人打赏支持
十月初五的月亮
粉丝 0
博文 71
码字总数 31441
作品 0
朝阳
Nginx Gzip模块启用和配置指令详解

参考一 http://www.111cn.net/sys/nginx/69492.htm 参考二 查找nginx安装的路径以及相关安装操作命令 参考三 http://blog.csdn.net/u011078940/article/details/51276765 Nginx的gzip模块是内...

james_laughing
2016/12/23
8
0
帮我看看这两段的区别

将网易几个图片域名加入web cache后 等待响应时间比没加入缓存之前要慢很多。 因为我是外行人 有些地方看不懂 还请大家帮忙看看这几个报头的区别。。 是不是说 等待响应时间慢是因为需要从外...

sepyj
2012/06/21
627
1
浏览器缓存相关的Http头介绍:Expires,Cache-Control,Last-Modified,ETag

缓存对于web开发有重要作用,尤其是大负荷web系统开发中。 缓存分很多种:服务器缓存,第三方缓存,浏览器缓存等。其中浏览器缓存是代价最小的,因为浏览器缓存依赖的是客户 端,而几乎不耗费...

pczhangtl
2013/11/15
0
0
ATS巧玩儿缓存策略增加动态服务吞吐量

缓存有个大原则,就是在不影响用户、不触犯法律的前提下,尽量多的将资源缓存到本地。哪些HTTP资源可以cache哪些不能cache,ATS对可缓存性有一套系统的判断机制,设置灵活,可以对全局进行配...

pypg
2016/04/05
249
0
Nginx压缩输出配置

随着网站内容不断增加,我们的网站上的内容和功能也变得丰富多彩,这时就会有一个问题出现----我们的网站加载会明显变慢,这对于网站的访客来说可不是一件愉快的事,那么我们该如何优化网站,...

运维猫
2016/04/28
0
0
面向站长和网站管理员的Web缓存加速指南

原文(英文)地址: http://www.mnot.net/cachedocs/ 版权声明:署名-非商业性使用-禁止演绎 2.0 这是一篇知识性的文档,主要目的是为了让Web缓存相关概念更容易被开发者理解并应用于实际的应...

随影求是
2012/03/16
0
0
Nginx学习笔记——gzip

配置详解 gzip on off 开启或关闭gzip,默认关闭 gzip_static on off 对于静态资源预先压缩 gzipcomplevel 4 压缩比(1-9),建议4 gzip_buffers 4 16k 安装原始数据大小以16k为单位的4倍申请...

涛洛洛
2016/08/18
26
0
浏览器 HTTP 协议缓存机制详解

最近在准备优化日志请求时遇到了一些令人疑惑的问题,比如为什么响应头里出现了两个 cache control、为什么明明设置了 no cache 却还是发请求,为什么多次访问时有时请求里带了 etag,有时又...

大数据之路
2015/01/19
0
16
nginx的详细使用说明(下)

1.gzipcomplevle 设置gzip压缩等级,等级越底压缩速度越快文件压缩比越小,反之速度越慢文件压缩比越大 param:1-9 example:gzipcomlevel 1; 2.gzip_types 设置需要压缩的MIME类型,非设置值不...

熊猫88
2016/01/10
210
0
Servlet 服务器 HTTP 响应

正如前面的章节中讨论的那样,当一个 Web 服务器响应一个 HTTP 请求时,响应通常包括一个状态行、一些响应报头、一个空行和文档。一个典型的响应如下所示: 状态行包括 HTTP 版本(在本例中为...

李序锴
2017/12/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

看看 LinkedList Java 9

终于迎来了 LinkedList 类,实现的接口就有点多了 Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, List<E>, Queue<E>。LinkedList是一个实现了List接口和Deque接口的双端链......

woshixin
15分钟前
0
0
算法 - 冒泡排序 C++

大家好,我是ChungZH。今天我给大家讲一下最基础的排序算法:冒泡排序(BubbleSort)。 冒泡排序算法的原理如下: 比较相邻的元素。如果第一个比第二个大(可以相反),就交换他们两个。 对每...

ChungZH
17分钟前
0
0
jquery ajax request payload和fromData请求方式

请求头的不同 fromData var data = { name : 'yiifaa'};// 提交数据$.ajax('app/', { method:'POST', // 将数据编码为表单模式 contentType:'application/x-ww...

lsy999
19分钟前
0
0
阿里P7架构师,带你点亮程序员蜕变之路

前言: Java是现阶段中国互联网公司中,覆盖度最广的研发语言。 掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。 有不少朋友问,成为Java架...

Java大蜗牛
21分钟前
1
0
Ecstore 在没有后台管理界面(维护)的情况如何更新表的字段

window 系统: 切换到:app\base 目录下: C:\Users\qimh>d: D:\>cd D:\WWW\huaqh\app\base 执行:D:\WWW\huaqh\app\base>cmd update linux 系统: 1># cd /alidata/www.novoeshop.com/app/......

qimh
25分钟前
0
0
设计模式-策略模式

策略模式 解释 对工厂模式的再次封装,使用参数控制上下文信息(将工厂返回的实例赋值给context field) 不会返回bean实例,只是设置对应的条件 调用context的方法(调用field的方法) 用户只...

郭里奥
28分钟前
0
0
python使用有序字典

python自带的collections包中有很多有用的数据结构可供使用,其中有个叫OrderedDict类,它可以在使用的时候记录元素插入顺序,在遍历使用的时候就可以按照原顺序遍历。 a = {"a":1,"b"...

芝麻糖人
58分钟前
0
0
RestTemplate HttpMessageConverter

RestTemplate 微信接口 text/plain HttpMessageConverter

微小宝
58分钟前
0
0
mysql视图/存储过程/函数/事件/触发器

--语法参考:https://dev.mysql.com/doc/ (当前用的是5.6) https://dev.mysql.com/doc/refman/5.6/en/sql-syntax-data-manipulation.html --视图 CREATE VIEW test.v AS SELECT * FROM t;......

坦途abc
今天
0
0
MySQL参数优化案例

环境介绍 硬件配置 cpu核心数 内存大小 磁盘空间 16核 256G 3T 软件环境 操作系统版本 mysql版本 表数目 单表行数 centos-7.4 mysql-5.7.22 128张表 2kw行 优化层级与指导思想 优化层级 MySQ...

小致dad
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部