ETags:验证和缓存最大年龄

ETags: Validation and Cache max-age

我使用 ETag 已经有一段时间了,我对它们的使用方式和功能感到满意。

但是,我有时会遇到 ETag 验证请求。在我的服务器上,我可以看到我的浏览器访问了资源 URL,然后得到了 "Not changed" 响应。但是,这仍然是一个请求。

一个聪明的网络服务器(我正在用 NodeJS 编写我的代码)如何避免在 cache-control: max-age=N 期间被验证?

例如,我的 max-age 表示 TTL 为 30 天。客户根本不应该在那个时候验证 Etag。这可能吗?

无法在服务器级别强制执行此操作,因为这是客户端决定的。

像 ETag 这样的缓存控制 headers 是提示而非指令。浏览器可以随意忽略这些提示(例如,当您刷新页面时,您明确要求浏览器重新检查资源)。一些浏览器还会定期重新检查资源。

也就是说,如果您的缓存控制 headers 设置正确,那么这些请求应该很少出现,并且正常情况下应该是不发送请求。

间歇性地 看到这个问题(Ubuntu 下的 FF45)。有些文件在每次重新加载时都会被检查,而大多数则不会。我不太确定什么会告诉 Firefox 应该在每次加载时检查这样或那样的文件。

根据 jscher2000 在 a blog 上的 post,Firefox 首先检查 Last-Modified,如果过时,则发送请求;请求将在 If-None-Match 中包含服务器 ETag 的值,我还可以看到 If-Modified-Since header.

Generally speaking, Firefox does not re-request or revalidate cached files that have not yet expired. You can change Firefox's behavior on the client side by changing a setting in about:config (apparently you need to clear the cache and restart Firefox for the change to take effect):

browser.cache.check_doc_frequency (defaults to after expiration) browser.cache.check_doc_frequency not working? @ mozillaZine Forums (clear cache/restart)

看起来我的 check_doc_frequency 参数设置为 3,这意味着它应该只检查被认为已过时的文档。

Possible values and their effects

0 — Check for a new version of a page once per session (a session starts when the first application window opens and ends when the last application window closes).
1 — Check for a new version every time a page is loaded.
2 — Never check for a new version - always load the page from cache.
3 — Check for a new version when the page is out of date. (Default)

我做的一件事是使用以下两个 headers:

Cache-Control: max-age=3600
Expires: Sun, Mar 27 2016 21:13:50

可能存在某种混淆,如果只定义了 max-age,那么您 运行 在某些奇怪的情况下会错过该特定情况。

为了以防万一,还有我的全header:

Cache-Control: max-age=3600,public
Connection: keep-alive, Keep-Alive
Date: Mon, 28 Mar 2016 02:56:20 GMT
Etag: 6b395ccb5b0a913f1828cce3e2756bdc
Expires: Mon, 28 Mar 2016 03:56:19 GMT
Keep-Alive: timeout=15, max=5
Server: Apache
Set-Cookie: ...

Connection 字段中重复的 Keep-Alive 值来自 Apache。