ETag 是 Entity Tag 的缩写,中文译过来就是实体标签的意思。在HTTP1.1协议中其实就是请求HEAD中的一个属性而已。

HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close <html>
<head>
<title>An Example Page</title>
</head>
<body>
Hello World, this is a very simple HTML document.
</body>
</html>

请注意第8行的 ETag: "3f80f-1b6-3e1cb03b"配置,那么为什么要用ETag呢?

ETag是HTTP1.1中才加入的一个属性,用来帮助服务器控制Web端的缓存验证。它的原理是这样的,当浏览器请求服务器的某项资源(A)时, 服务器根据A算出一个哈希值(3f80f-1b6-3e1cb03b)并通过 ETag 返回给浏览器,浏览器把"3f80f-1b6-3e1cb03b" 和 A 同时缓存在本地,当下次再次向服务器请求A时,会通过类似 If-None-Match: "3f80f-1b6-3e1cb03b" 的请求头把ETag发送给服务器,服务器再次计算A的哈希值并和浏览器返回的值做比较,如果发现A发生了变化就把A返回给浏览器(200),如果发现A没有变化就给浏览器返回一个304未修改。这样通过控制浏览器端的缓存,可以节省服务器的带宽,因为服务器不需要每次都把全量数据返回给客户端。

注:HTTP中并没有指定如何生成ETag,哈希是比较理想的选择。

通常情况下,ETag更类似于资源指纹(fingerprints),如果资源发生变化了就会生成一个新的指纹,这样可以快速的比较资源的变化。在服务器端实现中,很多情况下并不会用哈希来计算ETag,这会严重浪费服务器端资源,很多网站默认是禁用ETag的。有些情况下,可以把ETag退化,比如通过资源的版本或者修改时间来生成ETag。

如果通过资源修改时间来生成ETag,那么效果和HTTP协议里面的另外一个控制属性(Last-Modified)就雷同了,使用 Last-Modified 的问题在于它的精度在秒(s)的级别,比较适合不太敏感的静态资源。

后记

在友盟的时候做过一个项目 - 在线参数,这个功能在很多游戏类App中非常流行,也有很多App会通过它来控制内置广告的开关,曾经一度流量过大以至于阿里那边发邮件过来要我们关闭这个服务区(这是个免费的服务)。为了继续造福群众,我们做了一些优化流量的措施:

  1. 减少SDK请求的次数
  2. 设计了一种服务器端缓存验证机制

前者是因为很多开发者把调用方法写在了Activity里面,这样每次Activity重建的时候都会导致给服务器发请求。但是对于SDK来说无法判断请求是开发者故意发起的还是由于Activity重建导致的,所以解决这个问题需要开发者配合 - 这明显是不可能的。考虑到在线参数并不会经常性的发生变化,SDK限制了请求间隔为10分钟 - 考虑大部分App的声明周期是3 - 10 分钟(对于读书、视频等媒体类应用例外),这等于App每次启动只能请求一次服务器,这种限制在开发者DEBUG阶段会造成奇怪的问题 - 明明更新了在线参数,本地却不起效果。

第二个措施其实是进一步优化,在最早设计在线参数的时候已经添加了服务器端的验证机制 - 每次请求数据的时候带上服务器返回的最后修改时间,如果服务器端发现数据没有变化,那么就不再返回数据。但是这个协议是在HTTP-Body里面通过私有协议实现的,每次请求服务器的时候依然会发送大量数据(<1K),所以优化的措施是每次先发送一个最简的协议给服务器如果数据有变化再发送一个标准的协议给服务器取回数据。

当时我对HTTP协议并不熟悉,这些设计都是通过私有协议实现的,其实完全可以通过HTTP来实现,这样可以较好的分离控制逻辑和业务数据。

作者:ntop
链接:https://www.jianshu.com/p/a3ea9619c38d
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

什么是ETag的更多相关文章

  1. 使用ETag进行session的降级

    回顾 在web后台开发中我们经常需要存储一些变量到session中进行暂存,最为特殊的就是"购物车",由于http的无状态特性,因此我们需要在客户端打上一个标记,唯一的标示客户端并 ...

  2. 浏览器请求页面时Etag和cache的区别

    etag:简单的说就是服务器收到客户端的请求后,根据返回的内容计算出来一个etag值,返回给客户端,当客户端下次再请求相同路径的时候会带上之前的etag值,服务器端会根据这次请求应该返回的内容计算出新 ...

  3. HTTP参数中Etag的重要性

    在研究tornado时,有个Etag比较好奇,从网上查询摘录如下:

  4. http缓存之304 last-modified,cache-control:max-age,Etag等

    因最近客户端慢的问题,系统分析了下http协议缓存问题.本文主要记录总结http缓存相关知识. 1. 讨论涉及的要点 访问返回类 > 访问返回200 OK > 访问返回200 (from ...

  5. 浏览器缓存相关的Http头介绍:Expires,Cache-Control,Last-Modified,ETag

    转自:http://www.path8.net/tn/archives/2745 缓存对于web开发有重要作用,尤其是大负荷web系统开发中. 缓存分很多种:服务器缓存,第三方缓存,浏览器缓存等.其中 ...

  6. kangle 默认支持ETag,如果是用kangle做源不会识别,但是做cdn或反向代理会自动识别

    kangle  默认支持ETag,如果是用kangle做源不会识别,但是做cdn或反向代理会自动识别

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

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

  8. Etag缓存在PHP和NodeJS中的实现

    HTTP 提供了许多页面缓存的方案,其中属 Etag 和 Last-Modified 应用最广.本文会先介绍 Etag 的应用场景,然后说说他在 php 和 node 中的使用. 本文地址:http: ...

  9. Last-Modified,Etag,Expire区别

    Last-Modified 是什么 Last-Modified 是 HttpHeader 中的资源的最后修改时间,如果带有 Last-Modified ,下一次发送 Http 请求时,将会发生带 If ...

  10. Web前端性能优化教程08:配置ETag

    本文是Web前端性能优化系列文章中的第五篇,主要讲述内容:配置ETag.完整教程可查看:Web前端性能优化 什么是ETag? 实体标签(EntityTag)是唯一标识了一个组件的一个特定版本的字符串, ...

随机推荐

  1. 解决 KendoUI TabStrip 高度 100% 问题

    摘自: http://www.kendoui.com/forums/kendo-ui-web/tabstrip/forcing-tabstrip-to-take-up-100-of-it-s-pare ...

  2. 快速实现一个生产者-消费者模型demo

    package jesse.test1; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.Blo ...

  3. 2017.12.14 Mybatis物理分页插件PageHelper的使用(一)

    参考来自: http://www.360doc.com/content/15/0728/15/12642656_487954693.shtml https://www.cnblogs.com/digd ...

  4. ini配置文件的读取

    .ini 文件是Initialization File的缩写,即初始化文件.是windows的系统配置文件所采用的存储格式,统管windows的各项配置,一般用户就用windows提供的各项图形化管理 ...

  5. 浏览器开发调试工具的秘密 - Secrets of the Browser Developer Tools

    来源:GBin1.com 如果你是一个前端开发人员的话,正确的了解和使用浏览器开发工具是一个必须的技能. Secrets of the Browser Developer Tools是一个帮助大家了解 ...

  6. 服务器变量 超级全局数组$_SERVER (附加超简单表单与html5表单属性)

    001.html <html> <head><title>user log</title> <meta http-equiv="cont ...

  7. Eclipse中,快捷键使用总结

    (1)Alt+shift+L:new ReadItem().readItems(file);的返回对象是Map<String,String>用这个快捷键有两个效果示例1:输入光标停在new ...

  8. JMeter 六:Listener

    参考:http://jmeter.apache.org/usermanual/listeners.html Listener是用来展示Sampler结果的元件. 结果可以被展示在树.表格.图表或者简单 ...

  9. Android学习路线(二十一)运用Fragment构建动态UI——创建一个Fragment

    你能够把fragment看成是activity的模块化部分.它拥有自己的生命周期,接受它自己的输入事件,你能够在activity执行时加入或者删除它(有点像是一个"子activity&quo ...

  10. 进程上下文切换 – 残酷的性能杀手(上)(转载cppthinker.com)

    对于服务器的优化,很多人都有自己的经验和见解,但就我观察,有两点常常会被人忽视 – 上下文切换 和 Cache Line同步 问题,人们往往都会习惯性地把视线集中在尽力减少内存拷贝,减少IO次数这样的 ...