HTTP:生成ETag标头

时间:2020-03-05 18:38:17  来源:igfitidea点击:

如何为资源文件生成ETag HTTP标头?

解决方案

回答

etag是服务器发送给客户端的任意字符串,客户端在下次请求文件时会将其发送回服务器。

etag应该可以基于文件在服务器上计算。有点像校验和,但是我们可能不想校验每个发送出去的文件的校验和。

server                client

        <------------- request file foo

 file foo etag: "xyz"  -------->

        <------------- request file foo
                       etag: "xyz" (what the server just sent)

 (the etag is the same, so the server can send a 304)

我建立了一个格式为"文件索引节点号/日期戳/文件大小"的字符串。因此,如果在将文件提供给客户端之后在服务器上对其进行了更改,则如果客户端重新请求,则新生成的etag将不匹配。

char *mketag(char *s, struct stat *sb)
{
    sprintf(s, "%d/%d/%d", sb->st_ino, sb->st_mtime, sb->st_size);
    return s;
}

回答

来自http://developer.yahoo.com/performance/rules.html#etags:

By default, both Apache and IIS embed data in the ETag that dramatically reduces the odds of the validity test succeeding on web sites with multiple servers. 
  
  ...
  
  If you're not taking advantage of the flexible validation model that ETags provide, it's better to just remove the ETag altogether.

回答

只要资源表示形式发生变化,它就会发生变化,那么如何生产它完全取决于我们。

我们应该尝试以其他方式生产它:

  • 不需要我们在每个有条件的GET上重新计算它,并且
  • 如果资源内容没有更改,则不会更改

如果我们不将计算出的哈希值与文件一起存储,则使用内容哈希值会导致我们在#1处失败。

如果重新排列文件系统或者从多个服务器提供内容,则使用索引节点号可能导致我们在#2处失败。

一种可行的机制是使用完全依赖于内容的内容,例如SHA-1哈希或者版本字符串,只要资源内容发生更改,便会计算并存储一次。

回答

我建议不要使用它们,而应使用最后修改的标头。

Askapache对此有一个有用的文章。 (因为它们几乎完成了似乎所有的工作!)

http://www.askapache.com/htaccess/apache-speed-etags.html