【问题标题】:Should HTTP 304 Not Modified-responses contain cache-control headers?HTTP 304 Not Modified-responses 是否应该包含缓存控制标头?
【发布时间】:2010-12-07 22:38:30
【问题描述】:

我试图理解这一点,并搜索了类似的问题,但我仍然没有 100% 了解它应该如何工作。

我在请求图像资源时收到此响应:

Response Headers
    Server  Apache-Coyote/1.1
    Date    Mon, 19 Oct 2009 09:04:04 GMT
    Expires Mon, 19 Oct 2009 09:06:05 GMT
    Cache-Control   public, max-age=120
    Etag    image_a70703fb393a60b6da346c112715a0abd54a3236
    Content-Disposition inline;filename="binary-216-420"
    Content-Type    image/jpg;charset=UTF-8
    Content-Length  4719

所需的行为是客户端应将此缓存 120 秒,然后再次从服务器请求它。在 120 秒内,没有请求发送到服务器。

然后,120 秒后,发送请求并收到 304 响应:

Response Headers
    Server  Apache-Coyote/1.1
    Date    Mon, 19 Oct 2009 09:06:13 GMT

Request Headers
    Host    localhost:8080
    User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
    Accept  image/png,image/*;q=0.8,*/*;q=0.5
    Accept-Language en-us,no;q=0.8,sq;q=0.7,en;q=0.5,sv;q=0.3,nn;q=0.2
    Accept-Encoding gzip,deflate
    Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
    Keep-Alive  300
    Connection  keep-alive
    Referer http://localhost:8080/cms/site/0/en/home
    Cookie  JSESSIONID=768ABBE1A3BFABE3B535900233330650; versionsCssDisplayState=block; iceInfo=iceOn:false,activePortletKey:,icePagePanelX:1722,icePagePanelY:3
    If-None-Match   image_a70703fb393a60b6da346c112715a0abd54a3236

到目前为止,一切顺利。但是,在下一个请求(大约 120 秒)时,我会认为资源应该被缓存 120 秒。另一方面,我在浏览器 (Firefox) 中看到的是,它从此时开始总是请求资源并接收 304 响应。

我应该在 304 响应中附加缓存控制标头吗?从我在规范中可以读到的内容,似乎应该省略缓存控制设置,并且缓存应该自动将其缓存 120 秒?

【问题讨论】:

    标签: html http-headers etag


    【解决方案1】:

    RFC7232 更新 RFC2616 说:

    生成 304 响应的服务器必须生成任何 以下将在 200 (OK) 中发送的标头字段 对同一请求的响应:Cache-Control、Content-Location、Date、 ETag、Expires 和 Vary。

    【讨论】:

    • max-age 中的 120 秒是否应该由 304 刷新(如 Justin 在上一段中所述)?还是 validation-duration 不应该被 304 响应刷新?
    • @Pacerier 如果您发送与 200 相同的标头值,那么是的,它将被刷新。
    【解决方案2】:

    理论上,您不必为 304 发送 Cache-Control —— 收件人应该继续使用它从原始 200 接收到的缓存指令。但是,正如您所发现的,实际上,如果您不要一直发送 Cache-Control,浏览器会忽略你最初发送的缓存指令,并恢复到它们自己的默认启发式。

    因此,在实践中,您应该在 304 中包含与 200 相同的 Cache-Control。规范仅要求您将其发送为 304,如果它与您之前发送的不同(请参阅10.3.5 304 Not Modified) -- 但它当然不会禁止你在相同的时候重复它。

    并专门回应另一个答案(结构)中的错误观点:

    1. 确实希望中间缓存来缓存响应(即更新资源的缓存条目)。它们将适当地响应来自客户端的请求,使用 200 或 304,具体取决于客户端是否包含像 If-Modified-Since 这样的条件标头。

    2. 120 秒的 ttl 由 304 刷新(因此同一客户端至少在 120 秒内不应再次请求同一资源)。而客户端,只要他们仍然有缓存的内容,继续对资源发出有条件的请求,您可以继续使用 304 响应。

    【讨论】:

      【解决方案3】:

      如果我理解正确,那么浏览器实际上缓存了 120 秒,并且您的服务器正在响应 304 Not Modified 到后续的 If-Modified-Since 请求。当最终用户访问相同的 URL 时,会发生此“IMS”请求。此时浏览器可以发送一个 If-Modified-Since 请求。浏览器想知道它是否显示过时的内容。这看起来很正常。

      收到此请求后,您的服务器应回复 200 OK, 304 Not Modified(或 4XX,如有必要)。

      我认为您不应该将服务器设置为发送带有 304 响应的 Cache-Control 标头,原因有两个:
      1.您不希望任何中间缓存来缓存该 304 响应(它们有可能)
      2. 120秒的TTL不会被304响应刷新。从 200 OK 响应开始,浏览器会将对象保留 120 秒。 120 秒后,浏览器应该发送 GET 请求,而不是 If-Modified-Since,因此您的服务器将响应文件的字节,而不仅仅是 304 响应。

      请注意,浏览器不会在 120 秒后再次自动请求文件,除非最终用户通过页面加载或直接在地址栏中输入 URL 来明确请求文件(或者除非您有控制该功能的自定义应用程序不知何故)。

      编辑了第一段以更好地阅读(希望)

      【讨论】:

      • 嗯,我这边可能有点不清楚,但我想实现什么:1)第一次请求,将cache-control设置为在客户端缓存一段时间;最大年龄。 2)当达到max-age时,客户端应该发送一个新的请求。 3) 如果服务器上的内容没有改变,则返回 304。 4) 浏览器应该再次缓存 max-age 时间。 5) 在 max-age 之后的进一步请求中,获得 304 响应并更新客户端缓存。现在,在初始 200 和 max-age 之后,它“循环”向服务器发送请求,并以 304 作为响应。再说一次,也许我想要实现的不是一种有效的方法?
      • 这是我的看法:1) 第一个请求,200 OK,通过 max-age 设置缓存控制。 2) 如果客户端在文件过期后发出后续请求,它应该发出 GET 请求。否则,IMS 请求。 3) 如果是 GET 请求,200 OK。如果是 IMS,则 304 未修改或 200 正常。 4) 重新缓存文件,或保留当前副本,直到 max-age 过期并再次请求,在这种情况下转到上面的 #1。 5) 没有#5。 :) 如果您的目标是让最终用户尽可能长时间地保留文件并且只使用 304 响应(并且您不会更新文件),那么我建议更长的 max-age。
      • 添加到我的最后一条评论。我在 RFC 中没有看到任何内容表明您的方法不起作用或无效。但是,措辞表明它不打算以这种方式工作。 RFC 中的“请求”建议使用 GET 请求。响应 If-Modified-Since 请求返回 304,用于验证缓存。没有迹象表明 Cache-Control 标头可以包含在 304 响应中以更新当前缓存中的文件的标头。它表明 Cache-Control 标头通常设置为对标准 GET 请求的响应。
      • 如果这回答了您的问题,请继续并将其标记为已回答。如果不是,那么我或其他人会努力澄清。
      • 我仍然不确定它是否是使用 304 响应设置缓存控制标头的推荐方法。我发现了一些例子表明这是有效的,并且规范对此事并不是很清楚。我希望有人有一些经验支持 on 或其他理论。然而,到目前为止,我的所有测试都表明这可以正常工作,但是还有很多不同的场景需要考虑。
      猜你喜欢
      • 2021-08-16
      • 1970-01-01
      • 2023-04-08
      • 2012-12-08
      • 1970-01-01
      • 2013-03-24
      • 2018-10-06
      • 2012-08-28
      • 1970-01-01
      相关资源
      最近更新 更多