简介
ETAG在HTTP协议中的定义是资源实体的标记(entity tag),强标识一个资源。是缓存过期的一种代替方案(IF-MODIFIED-SINCE,IF-UNMODIFIED-SINCE)。服务器端资源一旦改变,ETAG值需要跟着改变。但是协议没有规定ETAG的计算方法,可以任意实现。一般对应静态资源(静态URL或文件)采用MD5摘要方式较好。
ETAG与IF-MATCH,IF-NONE-MATCH配合实现缓存方案,代替IF-MODIFIED-SINCE,IF-UNMODIFIED-SINCE(另外)
资源(Resource):URL唯一标识的资源,一个URL对应一个资源。
实现原理
- 服务器端创建资源,生成ETAG,每次修改也更新ETAG。
- 客户端首次访问资源,服务器返回资源实体内容和在头区中返回ETAG值,客户端保存实体内容和ETAG值。
- 客户端再次访问资源的时候,在头域(header)中加入“If-match:etag值”指令。
- 服务器接受到请求后,检查资源的ETAG值是否与请求的If-match指定的etag值相同(强匹配),如果匹配则响应304 Not Modified,表示资源未改变,客户端可以直接使用前面请求中保存的资源,如果不匹配才返回资源实体(entity,也就是body体).或者:客户端再次访问资源的时候,在header中加入“If-None-Match:etag值”,如果服务器的ETAG值匹配客户端请求 的etag值则返回412,表示条件冲突,不匹配则返回实体内容。
- 客户端继续使用缓存的资源。
- If-Match:匹配则返回实体内容,否则响应307,不返回实体内容。
- If-None-Match:不匹配则返回实体内容,否则响应412错误。
ETag比Last-Modified和 Expires 的优势
Last-Modified和Expires都是时间作为判断资源是否改变的标志存在一些隐患。
- 在秒级以内多次修改,Last-Modified和Expires无法表示出来,因为Last-Modified和Expires最小粒度为秒级。
- 对资源多次修改,但是最后又修改回最初的内容,实际上内容并没有改变。
- ETag值是根据实际内容变更才更新,所以可以更准确的标志资源。
实际应用
云存储中最为文件的tag,标记文件是否改变。一般使用MD5判断文件是否改变,也可以直接使用MD5值作为ETAG值。
问题:对大文件,修改一小部分内容后,更新ETAG,从新计算MD5,效率太低,解决方案啊~?