Etag学习

Etag是什么?

        Etag 是URL的Entity Tag,用于标示URL对象是否改变,区分不同语言和Session等等。具体内部含义是使服务器控制的,就像Cookie那样。

  HTTP协议规格说明定义ETag为“被请求变量的实体值” 。另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端。(从定义上看,比较笼统,还是不知道Etag究竟是何方东东)

 

Etag的作用是什么?

       Etag 主要为了解决 Last-Modified 无法解决的一些问题。

  1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

  2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)

  3、某些服务器不能精确的得到文件的最后修改时间;

  为此,HTTP/1.1 引入了 Etag(Entity Tags).Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说"2e681a-6-5d044840"这么一串看起来很神秘的编码。但是HTTP/1.1标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag需要放在""内。

 

Etag的原理:

        Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。常见的是使用If-None-Match.请求一个文件的流程可能如下:

  ====第一次请求===

  1.客户端发起 HTTP GET 请求一个文件;

  2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"2e681a-6-5d044840")(假设服务器支持Etag生成和已经开启了Etag).状态码200

  ====第二次请求===

  1.客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d044840

  2.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,不返回200,返回304,客户端继续使用本地缓存;

  流程很简单,问题是,如果服务器又设置了Cache-Control:max-age和Expires呢,怎么办?

  答案是同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.(不要陷入到底使用谁的问题怪圈)

 

Etag实例详解

       首先介绍下,我使用拦截http协议的插件,FF的tamper data。

    个人比较喜欢上猫扑网,下面盗用其图片来简单说说Etag的使用.

       当我首次访问这图片的时候,tamper data工具显示为:

      

 

从上图我们可以看到,服务器端返回响应值为200,并发送回了相应的网页内容,在http响应头中有etag消息头,值为

Etag="Fk40hnnqr90",我们不需要去关心这个响应头的内容是什么,我们只需要将这这个头信息的值记录下来,

 

接着我们刷新下FF,tamper data中显示如下:

 

从上图可以看出,If-None-Math的值跟我们首次访问网页的值是相同的,服务并没有重新发送图片到客户端,只是返回了304的状态。

 

服务端中Etag的实现(以apache为例)

.Apache首先判断是不是弱Etag,这个留在下面讲。如果不是,进入第二种情况:

  强Etag根据配置文件中的配置来设置Etag值,默认的Apache的FileEtag设置为:

  FileEtag INode Mtime Size

  也就是根据这三个属性来生成Etag值,他们之间通过一些算法来实现,并输出成hex的格式,相邻属性之间用-分隔,比如:

  Etag"2e681a-6-5d044840"

  这里面的三个段,分别代表了INodeMTime,Size根据算法算出的值的Hex格式,(如果在这里看到了非Hex里面的字符(也就是0-f),那你可能看见神了:))

  当然,可以改变Apache的FileEtag设置,比如设置成FileEtagSize,那么得到的Etag可能为:

  Etag"6"

  总之,设置了几个段,Etag值就有几个段。(不要误以为Etag就是固定的3段式)

  说明

  这里说的都是Apache2.2里面的Etag实现,因为HTTP/1.1并没有规定Etag必须是什么样的实现或者格式,因此,也可以修改或者完全编写自己的算法得到Etag,比如"2e681a65d044840",客户端会记住并缓存下这个Etag(Windows里面保存在哪里,下次访问的时候直接拿这个值去和服务器生成的Etag对比。

  注意

  不管怎么样的算法,在服务器端都要进行计算,计算就有开销,会带来性能损失。因此为了榨干这一点点性能,不少网站完全把Etag禁用了(比如Yahoo!),这其实不符合HTTP/1.1的规定,因为HTTP/1.1总是鼓励服务器尽可能的开启Etag。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值