创建ETag的最佳方法是什么?

28

如何以编程的方式生成网页的etag,这种做法是否被推荐?有些网站建议关闭etag,有些则建议手动生成,还有些建议保留默认设置 - 在这里哪种方法最好?


你的技术环境是什么?一些Web服务器具有丰富的内置支持。 - bzlm
Dupe-ish:https://dev59.com/questions/unVD5IYBdhLWcg3wWaVh - bzlm
6个回答

6

我建议对内容生成哈希值,例如md5($content)
此外,为了防止哈希碰撞,如果适用的话,可以添加内容元素的ID。


2
速度不太快,因为你需要读取文件内容,而这个文件可能有几兆字节长。如果再加上并发访问,那就是一个爬虫网站了。 - rr-
1
是的,对于会导致问题的大文件,以及如果 $content 已经可用/已读取的情况下,应该使用文件元数据(大小和时间戳)。 - blueyed

4
我刚刚启动了YSlow,它抱怨ETags的问题,所以我做了一些研究。根据Yahoo博客(请查看评论),问题在于默认的ETags实现使用文件inode号码或ntfs修订号码或其他服务器特定的内容作为哈希的一部分。虽然这样很快,但基本上阻止了同一文件被2个不同的服务器提供,并且会影响浏览器和下游缓存或负载平衡。

以前建议使用MD5 Hash是一个好主意,尽管你必须防止它成为性能问题。该建议的实现留给读者自行处理,尽管我认为这似乎是框架可以为您处理的事情。

对于我自己而言,由于我处于简单环境中,文件时间戳将足以满足需求,我只需在我的.htaccess文件中使用FileETag none关闭它们。这样就可以解决YSlow的问题,并且应该使事情回退到文件的最后修改日期。


3
当你严重依赖缓存时,ETags就显得很有意义。它们是资源状态的良好指示器(例如URL)。
例如,假设您使用ajax请求来获取用户的最新评论,并且您想知道是否有新评论。将ETag更改为警报可更廉价地检查其中的新内容。
因为如果ETag相同,则可以保留缓存,否则需要重建它。
在RESTful API中,ETags也非常有意义。
至于生成它,查看spec,我认为您几乎可以做任何您想要的事情。时间戳,哈希值,无论对您/您的应用程序有意义的都可以。

1
通常,反对使用ETAG的“站点”是雅虎,因为一些默认的Web服务器不能自动创建适用于服务器群的ETAG(这是雅虎声称的正确和准确之处)。 但是,如果您只有一个Web服务器,则没问题。否则,您需要检查您的Web服务器如何处理它,并采取适当的行动。

1

Mufasa,

雅虎(和 YSlow)实际上鼓励使用它们,但有一个警告,即自动生成的 ETag 会因服务器而异。

我还不能投票,所以我只能说我同意使用文件路径和时间戳的哈希值(或者如果由数据库内容表示,则为表名+主字段值+时间戳)的建议。


嗯,这就是我说的。 - Jon Adams
嗯,您说Yahoo不鼓励它们的使用,而我指出他们鼓励使用它们。 - eyelidlessness
如果你仔细阅读了Yahoo!关于这个主题的完整帮助文档,那么是的。但是YSlow本身似乎并不鼓励这样做。这个句子的语义是有争议的,但我的回答的重点仍然是有效的。 - Jon Adams

-5

ETags在你的网站生成器前使用某种缓存机制时确实有帮助。浏览器本身不使用它们,它们侦听“(if) modified since”或“age”头结构,据我所知。

无论如何,由于其简单的性质,提供带有ETag的http-header并不是问题。我听说许多Web服务器只需取文件的位置和文件的时间戳,并对此数据进行md5哈希。

例如,我们的软件使用一个简单但有效的ETag。我们软件中的每个“内容单元”(即html、jpeg、gif等)都有一个唯一的ID和版本号(即jpeg的ID为“17”,版本为“2”,这意味着它被更改了一次)。因此,ETag只是字符串“id-version”,这里是“17-2”。下一次更改将是“17-3”,以便缓存器识别更改,完全加载新的内容部分(一次)并将其存储在自己的缓存中。

但是,您也可以使用URL和时间戳(即文件的时间戳)。


13
否则浏览器就没有意义了,浏览器确实使用它们。例如,请参阅RFC 2068:http://www.freesoft.org/CIE/RFC/2068/187.htm。正如您所说,实体标签只需要足够详细,以便能够告诉浏览器实体本身已被修改。 - bzlm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接