【问题标题】:How should http cache actually work?http缓存应该如何实际工作?
【发布时间】:2013-08-15 11:42:50
【问题描述】:

我知道这实际上是一个古老的东西,但我确实对它以及它在开始时应该如何工作有疑问。所以我至少得到了这四个可以发送回客户端的重要缓存头(Last-ModifiedCache-ControlExpiresETag

问题 2.2 的示例情况:

假设我有一些包含文章的网站。 每 15 分钟到 7 天可能会有一篇新文章。 所以我将Cache-ControlExpires 设置为缓存15 分钟,以便客户端始终获得最新版本。

我现在对ETagLast-Modified的看法:

我只是在里面放了一些内容的哈希值,如果If-None-Match == ETag,我可以向客户端发送304

如果If-Modified-Since >= Last-Modified,我可以发送客户304

问题

  1. 我需要Cache-Control Expires 来支持所有浏览器吗?
  2. 看起来Cache-ControlExpires 只是告诉我的浏览器内容应该在计算机上缓存多长时间,对吧?
    • 所以我只能使用ETagLast-Modified 来确定我应该何时发送304 对吧?
    • 所以我可以将Cache-ControlExpires 设置为永远,如果ETagLast-Modified 更改了它,只需向客户端发送新版本?
      • 因为这适用于我的浏览器,但它适用于所有浏览器吗?
  3. 我需要ETag Last-Modified 来支持所有浏览器吗?
  4. Pragma 看起来像另一个类似于Cache-Control 的缓存头,哪些浏览器正在使用Pragma,我需要它吗?

【问题讨论】:

    标签: http http-headers browser-cache


    【解决方案1】:

    我是否需要Cache-ControlExpires 来支持所有浏览器?

    Cache-Control 是在 HTTP 1.1 中引入的,因此仅支持支持 HTTP 1.1 的客户端。自 HTTP 1.0 起支持 Expires。如果两者都指定,则Cache-Control 优先,Expires 将被完全忽略。


    看起来Cache-ControlExpires 只是告诉我的浏览器内容应该在计算机上缓存多长时间对吗?

    基本上,是的。如果Cache-Control 不存在(因此将使用Expires)或使用max-age 设置正确。


    所以我只能使用ETagLast-Modified 来确定何时应该发送304 对吧?

    在这里,您的问题开始令人困惑。您实际上需要检查 If-None-MatchIf-Modified-Since 标题。通常,浏览器在有条件的 GET 请求中只发送其中一个,如果它与服务器中的 ETagLast-Modified 的当前值匹配,则返回 304 以及 ETag 标头。请注意,如果浏览器出于某种原因同时发送了它们,那么您可以忽略 If-Modified-Since


    所以我可以将 Cache-ControlExpires 设置为永远,如果 ETagLast-Modified 更改了它,只需将新版本发送给客户端?

    没有。如果将其设置为永远,客户端将永远不会发送(条件)请求,直到最终用户按下 (Ctrl)+F5。您需要将 Cache-Control: max-ageExpires 设置为所需的缓存时间(可能是未来 15 分钟?)。


    因为这适用于我的浏览器,但它适用于所有浏览器吗?

    注意您的测试方式:按 F5 将始终发送有条件的 GET 请求。但是一个简单的页面到页面导航和表单提交(就像在现实世界中一样)不会发送有条件的 GET 请求!按 Ctrl+F5 将忽略缓存并发送全新的 GET 请求。


    我是否需要 ETag 和 Last-Modified 来支持所有浏览器?

    所有浏览器都支持。如果已经从服务器接收到 ETag,浏览器需要通过If-None-Match 发送回 ETag,并且浏览器需要执行有条件的 GET 请求。 Last-Modified 对他们来说是可选的,通常仅在资源上不存在 ETag 时才发送。另见RFC 2616 section 13.3.4


    Pragma 看起来像另一个类似于 Cache-Control 的缓存头,哪些浏览器正在使用 Pragma,我需要它吗?

    如果要缓存,则不需要它。仅当您想要缓存时才需要它(以覆盖 HTTP 1.0 客户端/代理,但其数量目前正在稳步减少)。


    如果您熟悉 Java,或者至少可以破译它,那么您可能会发现这篇文章很有帮助:FileServiet supporting resume and caching and GZIP

    另见:

    【讨论】:

    • 所以如果Cache-Control说缓存版本可以使用,浏览器甚至不会发送HTTP请求,对吧?因此,只有在Cache-Control 表示缓存版本已过时,但如果服务器以 304 响应,浏览器将仍然使用缓存版本,才会发送 HTTP 请求,对吗?如果这两个问题都是正确的,那么响应是否会在max-age=0 时被缓存(本地),或者仅当它至少是max-age=1 时才被缓存? (这样当服务器响应 304 时,就有了可以使用的东西。)
    • 没错。请注意,浏览器将继续发送有条件的 GET 请求,除非您将更新的 Cache-ControlExpires 标头与 304 一起返回,这基本上会延迟缓存更多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多