zoukankan      html  css  js  c++  java
  • REST笔记(五):你应该知道的HTTP头ETag

    在HTTP1.1规范中,新增了一个HTTP头信息:ETag。对Web开发者来说,它是一个非常重要的信息。它是用作缓存使

    用的两个主要的头信息之一 (另一个是Expires)。除此之外,在REST架构中,它还可以用于控制并发操作(上节中已经大

    致介绍AtomPub中控制并发的流程)。那么ETag是什么?它又几种类型?强ETag与弱ETag之间有什么区别。?如何计算

    ETag值?它与Last-Modified头信息在使用上有什么区别?本节主要围绕这几个方面叙述一下自己的理解。


    目录:

    1. 什么是ETag?
    2. 计算ETag值
    3. ETag的类型以及他们之间的区别
    4. ETag与Last-Modified头信息用途上的区别

    什么是ETag? 

    ETag:是实体标签(Entity Tag)的缩写。ETag一般不以明文形式相应给客户端。在资源的各个生命周期中,它都具有不

    值,用于标识出资源的状态。当资源发生变更时,如果其头信息中一个或者多个发生变化,或者消息实体发生变化

    ,那ETag也随之发生化。

    ETag值的变更说明资源状态已经被修改。往往可以通过时间戳就可以便宜的得到ETag头信息。在服务端中如果发回给

    消费者的相应一开始起就由ETag控制,那么可以确保更细粒度的ETag升级完全由服务来进行控制。服务计算ETag值,

    并在相应客户端请求时将它返回给客户端。

    计算ETag值

    在HTTP1.1协议中并没有规范如何计算ETag。ETag值可以是唯一标识资源的任何东西,如持久化存储中的某个资源关联

    的版本、一个或者多个文件属性,实体头信息和校验值、(CheckSum),也可以计算实体信息的散列值。有时候,为了计

    算一个ETag值可能有比较大的代价,此时可以采用生成唯一值等方式(如常见的GUID)。无论怎样,服务都应该尽可能的

    将ETag值返回给客户端。客户端不用关心ETag值如何产生,只要服务在资源状态发生变更的情况下将ETag值发送给它就行

    。下图为MSDN中,OutgoingResponse类中设置ETag值的截图:

    2011-12-24_105957

    从上图可以看出,在REST架构下,ETag值可以通过Guid、整数、长整形、字符串四种类型的参数传入SetETag方法,

    WCF服务发回给客户端的HTTP响应头中就包含了ETag值。另外OutgoingResponse类也有字符串属性:ETag直接给

    它赋值也能在HTTP响应头中写入ETag值。

    如下所示为使用文件属性计算ETag:

     public class ETag : IHeader
        {
            private string Value;
    
            public ETag(string value)
            {
                Value = value;
                WebOperationContext.Current.OutgoingResponse.ETag
            }
    
            #region IHeader 成员
    
            public void AddHTTPHeader(ResponseContext context)
            {
                context.WriteHttpHeader(Value);
            }
    
            #endregion
        }
    获取ETag:
    ETag eTag = new ETag(fileInfo.Name+fileInfo.LastWriteTimeUtc.ToString())

    计算ETag值时,需要考虑两个问题:计算与存储。如果一个ETag值只需要很小的代价以及占用很低的存储空间,那么

    我们以在每次需要发送给客户端ETag值值的时候计算一遍就行行了。相反的,我们需要将之前就已经计算并存储好

    的ETag值发送给客户端。之前说:将时间戳作为字符串作为一种廉价的方式来获取ETag值。对于不是经常变化的消息,

    它是一种足够好的方案。注意:如果将时间戳做为ETag值,通常不应该用Last-Modified的值。由于HTTP机制中,所

    以当我们在通过服务校验资源状态时,客户端不需要进行相应的改动。计算ETag值开销最大的一般是计算采用哈希算法

    获取资源的表述值。可以只计算资源的哈希值,也可以将头信息和头信息的值也包含进去。如果包含头信息,那么注意

    不要包含计算机标识的头信息。同样也应该避免包含Expires、Cache-Control和Vary头信息。注意:在通过哈希算法

    计算ETag值时,先要组装资源的表述。若组装也比较耗时,可以采用生成GUID的方式。优化ETag值的获取。

    ETag的类型以及他们之间的区别

    ETag有两种类型:强ETag(strong ETag)与弱ETag(weak ETag)。

    强ETag表示形式:"22FAA065-2664-4197-9C5E-C92EA03D0A16"。

    弱ETag表现形式:w/"22FAA065-2664-4197-9C5E-C92EA03D0A16"。

    强、弱ETag类型的出现与Apache务器计算ETag的方式有关。Apache默认通过FileEtag中FileEtag INode Mtime Siz

    e的配置自动生成ETag(当然也可以通过用户自定义的方式)。假设服务端的资源频繁被修改(如1秒内修改了N次),此时

    如果有用户将Apache的配置改为MTime,由于MTime只能精确到秒,那么就可以避免强ETag在1秒内的ETag总是不同而

    频繁刷新Cache(如果资源在秒级经常被修改,也可以通过Last-Modified来解决)。


    ETag与Last-Modified头信息用途上的区别

    按照HTTP标准,Last-Modified只能精确到秒级。ETag的出现可以很好的解决这个问题。在用途上,ETag常与

    If-None-Match或者If-Match一起,由客户端通过HTTP头信息(包括ETag值)发送给服务端处理。ETag使用如下:

    Get /Order/36 Http1.1

    If-Match:"22FAA065-2664-4197-9C5E-C92EA03D0A16"

    或If-None-Match:"22FAA065-2664-4197-9C5E-C92EA03D0A16"

    Last-Modified常与If-Modified-Since一起由客户端将Last-Modified值包括在HTTP头信息中发给服务端进行处理。

    其使用如下:

    If-Modified-Since:Sat,24 Dec 2011 11:55:36 GMT

  • 相关阅读:
    openldap
    Java实现 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…
    Java实现 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P1567 统计天数
    Java实现 洛谷 P1567 统计天数
  • 原文地址:https://www.cnblogs.com/tyb1222/p/2300246.html
Copyright © 2011-2022 走看看