HTTP ETag
Etag全称EntityTags,HTTP1.1中才加入的,Response Header一个属性,用来帮助服务器控制Web端的缓存验证。由服务器端生成,并且随着文件的改变而改变。HTTP规范从未指定生成ETag的方法。
ETag是一个不透明的标识符,由Web服务器根据URL上的资源的特定版本而指定。如果那个URL上的资源内容改变,一个新的不一样的ETag就会被分配。用这种方法使用ETag即类似于指纹,并且他们能够被快速地被比较,以确定两个版本的资源是否相同。ETag的比较只对同一个URL有意义——不同URL上的资源的ETag值可能相同也可能不同,从他们的ETag的比较中无从推断。
既然已经有了Last_Modified,为什么还需要ETag呢?因为UNIX记录MTIME只能精确到秒,假如1秒内修改N次,Last_Modified就无法应对了。
Examples
ETag: W/"<etag_value>>" --弱校验ETag
ETag: "<etag_value>" --强校验ETag
强校验的ETag匹配要求两个资源内容的每个字节需完全相同,包括所有其他实体字段(如Content-Language)不发生变化。允许重新装配和缓存部分响应,以及字节范围请求。
弱校验的ETag匹配要求两个资源在语义上相等,这意味着在实际情况下它们可以互换,而且缓存副本也可以使用。不过这些资源不需要每个字节相同,因此弱ETag不适合字节范围请求。当Web服务器无法生成强ETag不切实际的时候,比如动态生成的内容,弱ETag就可能发挥作用了。
原理
- 客户端请求服务器资源A时,服务器计算出一个哈希值作为ETag的值放在Response Header中返回给客户端,客户端缓存资源A和它的ETag。
ETag: "12345678abcdefg"
- 客户端再次请求资源A时,把缓存的ETag值放在Request Header的If-None-Match属性中。
If-None-Match: "12345678abcdefg"
- 服务器再次计算A的哈希值并和浏览器请求的值做比较,若资源没有变化,则哈希值一致,就会返回304 Not Modified,客户端使用本地缓存。
304会返回空响应体,客户端会从本地缓存中取数据。
nginx配置
nginx在1.3.3版本加入后默认开启。
