对于 Github API 条件请求,ETag 或 Last-Modified 哪个更可靠?

unb*_*dev 6 etag last-modified github-api

Github API指定了两个可在条件请求中使用的标头,Last-Modified以及ETag. 查询API时哪个更可靠?

对于上下文:当在大型存储库的每个子目录上使用 api 端点时 GET /repos/:owner/:repo/git/trees/:sha,每个响应都包含相同的last-modified值(即使 github 上的存储库显示不同的创作日期),而etag每个响应的值都不同。我想知道这是否ETag是存储库内容状态更改的更精细的表示(用于缓存目的)。

Von*_*onC 7

阅读“ ETags:HTTP 1.1 的一个非常贴心的功能”,它说:

ETag 允许使用特定于应用程序的“不透明令牌”缓存动态内容

ETag(或实体标记)是一种不透明标记,用于标识特定 URL 所服务的组件的版本。令牌可以是用引号括起来的任何内容;通常它是内容的 md5 哈希值,或者内容的 VCS 版本号。

如果答案的内容相同,则 ETag 每次都应该相同。

我刚刚用https://api.github.com/repos/VonC/gopanic/git/trees/master测试了它,实际上W/"34a03ea1d4dc0b5d533ecf8d36492879"即使重复调用它的 ETag 仍然存在。

但是如果我获取每个子文件夹的树,那么 ETag 会有所不同,因为它代表不同响应内容的签名。

ETag 的优点是它不依赖于日期(其时钟可能因各种原因而变化),而是依赖于答案的内容:如果不变,则它


警告:布莱斯在评论中指出:

etag值特定于服务器,例如 GitHub 可能会使用 blob 的哈希值,但也许并不总是如此。
其他提供商甚至可能不会这样做,例如 Apache过去使用的是inodefor 。etags

  • 如果“ETag”与发送令牌的“Authorization”标头结合使用,则每次使用一个令牌发出请求都会响应 304,以防文档没有更改,但如果您发送相同的 ETag 但使用不同的令牌无论文档是否更改,端点都会响应 200。那么有没有一种方法可以知道文档是否更改但无需中继发送的令牌呢?考虑到所有 github api 端点的“Last-Modified”标头均不可用(响应标头中缺失)。 (2认同)

Dan*_*nin 5

不幸的是,至少在 2019 年 8 月 1 日的状态下,GitHub API 和/releases/latest端点ETag并未给出一致的值。

大多数时候,它会给你一致的、不变的ETag值,但随机地(有时经常)ETag会有所不同。请参阅我的示例,我运行了几次 API 调用:

curl -IsL -H "Accept-Encoding: gzip" https://api.github.com/repos/mautic/mautic/releases/latest | grep -P '^(HTTP/|ETag:|X-RateLimit-Remaining|Last-Mod)'
Run Code Online (Sandbox Code Playgroud)

第一个结果:

HTTP/1.1 200 OK
X-RateLimit-Remaining: 56
ETag: W/"b86f015c353e7c1d773f1f781d4cf822"
Last-Modified: Mon, 25 Mar 2019 23:14:15 GMT
Run Code Online (Sandbox Code Playgroud)

几次之后:

HTTP/1.1 200 OK
X-RateLimit-Remaining: 59
ETag: W/"9f670edf97e04c5c23cce74457be61a3"
Last-Modified: Mon, 25 Mar 2019 23:14:15 GMT
Run Code Online (Sandbox Code Playgroud)

请注意如何Last-Modified保持完整,因此GET仅使用该标头进行条件操作将比ETag.