全称为:Entity Tag,意思是实体标签,从名字上看,是对于某种实体的一个标识。它的作用是用一个特殊的字符串来标识某个资源的“版本”,客户端(浏览器)来请求的时候,可以比较,如果ETag一致,则表示该资源并没有修改过,客户端(浏览器)可以使用自己缓存的版本。
## ETag工作原理 ##
当用户第一次请求某个资源(通常为静态资源)的时候,正常情况下,他将得到一个状态码为200的响应,并且在响应头部中会包含一个ETag的信息(ETag "6ab823201a4ece1:0"(不同的服务器可能会有所不同)),如果用户再次请求这个资源的话,浏览器会尝试在请求头部中包含这个信息,以便服务器可以比较,确定是要再次发送资源的内容。如果发现浏览器提供的值与该资源实际的值是一样的,它就会返回了304的状态码,而且不需要在响应的正文里面包含任何实际内容。浏览器得到304这个状态码之后,就知道该资源并没有被修改,所以直接使用本地缓存的版本。
## ETag功能 ##
主要能提供对资源的版本标识,以避免无谓的重复下载。提高了性能。
## Expires 、 Cache-Control 、 ETag 区别 ##
**Expires:**
服务器通过这个Header告诉浏览器,某资源直到某个时间才会过期,所以在没有过期之前,浏览器就直接使用本地的缓存了。
**问题:**
因为这是时间是由服务器发送的(UTC),但如果服务器时间和客户端事件存在不一致,可能会有些问题。可能存在版本的问题,因为如果在到期之前修改过了,客户端是不会知道的。
**Cache-Control **
服务器通过一个Header(Last-Modified)告诉浏览器,某资源最后修改的时间,浏览器在请求的时候,包含一个Header(If-Modified-Since),然后服务器可以进行比较,如果在该时间后没有修改过,则返回304。它比Expires多很多选项设置。
**问题:**
Last-Modified 也是一个时间,但该时间只能精确到秒,如果在同一个秒中有多次修改(这个在现在的环境下应该确实是可能的),则可能会发生问题。
**ETag **
可以更加精确地判断资源是否被修改,因为它不是一个时间值,而是对时间经过处理的一个长整型数值,浏览器发起新请求时需要包含 If-None-Match
**问题:**
如果部署在服务器场环境中,配置不当的话,可能每个服务器会对相同的资源生成不一样的ETag,这样就增加了重复下载的可能性。
**优先级从大到小:**
ETag、Cache-Control、Expires