鸦杀's Blog

什么是Etag

2016-07-25

先来看一下百度百科的解释:

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

我觉得它的另一个解释:与web资源关联的记号可能更容易理解一点


当我们请求web资源的时候,在http响应头中返回了ETag的值,如下图。

图1

它用来做什么呢?

这与浏览器缓存有关。在启用浏览器缓存的情况下,重复请求的相同的资源,浏览器会返回304(Not Modified)。浏览器是怎么判断资源有没有被修改的呢?这就需要依赖请求头中的ETag与Last-Modified了,步骤如下:

1、客户端get请求资源,服务器返回资源,并在响应头中带上了ETag与Last-Modified的值。
2、客户端将资源缓存在本地
3、客户端再次请求这个资源,在启用缓存的情况下,将上次请求的ETag属性值作为If-None-Match的值,Last-Modified的值作为If-Modified-Since随请求头发给服务器。
4、服务器判断资源现有的ETag与If-None-Match的值是否相等,如果相等,会返回304和空的响应体。浏览器根据304取本地缓存。

请求与响应如下图

图2


补充说明,在测试这个例子的时候,发现状态码206也与ETag有关。

206一般是在资源的前一次请求被中断,再次请求资源的时候,返回的状态码。如果我们在请求头中看到Accept-Ranges:bytes,说明服务器是支持206的。

从资源已经开始下载的地方开始下载,其实也就是断点续传了。断点续传用到了Range、Content-Range与If-Range字段,它从http 1.1开始支持。

看下面两张图,分别为请求头与响应头的对比

请求头

响应头

字段说明:

Range

用于请求头中,指定第一个字节的位置和最后一个字节的位置,pos从0开始计数,一般格式:

Range:(unit=first byte pos)-[last byte pos]

Content-Range

用于响应头,它指定了响应覆盖的范围和整个资源的大小。一般格式:

Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]

If-Range

用于请求头,If-Range的意思是:如果资源未修改,那么发送缺失的部分。如果资源修改了,那么发送整个资源。它的值为之前第一次请求响应头中的ETag的值,如果没有ETag,就取Last-modified的值,服务器接收到第二次请求后,会根据ETag或者Last-modified比较,判断资源有没有被修改。如果修改,状态码为200,如果没有修改,状态码为206.

扫描二维码,分享此文章