设定ETags (Configure ETags)
tag:server
实体标签(ETags)是服务器和浏览器用于确定浏览器中缓存的组件和服务器中的是否对应的一种机制。("entity"是组件的另一种说法:图片、脚本、样式表等等)添加 ETags用于辨别组件提供了比单纯利用“最后修改时间”更为灵活的机制。ETag
是一个唯一标识组件的特定版本的字符串。它的唯一格式规范是字符串必须被引号引用。来源服务器使用ETag响应头来设定一个组件的ETag:
HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195
当浏览器晚些时候需要检测一个组件时,它使用If-None-Match 头部把ETag传回来源服务器。如果ETag匹配了,会返回一个304状态码,在这个例子里它会减少12195个字节的响应:
GET /i/yahoo.gif HTTP/1.1
Host: us.yimg.com
If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT
If-None-Match: "10c24bc-4ab-457e1c1f"
HTTP/1.1 304 Not Modified
ETag的问题是它们往往在网站的一个服务器中被设为唯一的,当浏览器从一个服务器得到了组件并在稍后试图到另一个服务器验证时,ETag会不匹配,而这在使用多个服务器来处理请求的网站中是很常见的。默认情况下,Apache和IIS在ETag中嵌入的数据戏剧性的减少了应用多台服务器的网站的ETag验证成功几率。
Apache1.3和2.新版本的ETag格式是inode-size- timestamp。虽然一个给定的文件在多台服务器中处于同一个目录,而且有同样的大小,权限,时间戳,但它的inode在不同服务器中是不同的。
IIS5.0和6.0有同样的问题。IIS中ETag的格式是Filetimestamp:ChangeNumber。 ChangeNumber用来跟踪IIS配置的改变次数。一个网站的所有IIS不可能有相同的ChangeNumber。
这导致的结果是,Apache和IIS对完全相同的组件产生的ETag在不同服务器间不能匹配。如果ETags不匹配,用户不会得到小而快的304响应,而是一个普通的200响应和组件的所有数据。如果你把你的网站放在了一个服务器里,这不会是一个问题。但如果你的网站有多台服务器,而且你使用了Apache和IIS 默认的ETag配置,你的用户会访问页面的速度会变慢,你的服务器加载的程度更高,消耗了更大的带宽,代理服务器不能有效的缓存你的内容。即使你的组件有一个ar future Expires头部,当用户重载或者刷新页面时,依然会发送一个GET请求。
如果你不打算利用ETags提供的灵活的验证模式,你最好把ETag统统移除。Last-Modified头部的验证方式给予组件的时间戳。移除ETag 同时减少响应和随后的请求中的HTTP头部大小。这篇微软的支持文档描述了怎样在IIS中移除 ETags。在Apache中,你只要在Apache配置文件中添加如下一行:
FileETag none