我试图理解这一点,并搜索了类似的问题,但我仍然没有 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 秒?

有帮助吗?

解决方案

理论上,您不必为 304 发送 Cache-Control——接收者应该继续使用从原始 200 接收到的缓存指令。然而,正如您所发现的,在实践中,如果您不继续发送 Cache-Control,浏览器将忽略您最初发送的缓存指令,并恢复到它们自己的默认启发式。

因此,在实践中,您应该在 304 中包含与 200 相同的 Cache-Control。该规范仅要求您在与之前发送的内容不同时发送 304(请参阅 10.3.5 304 未修改)——但它当然不会禁止你在相同的情况下重复它。

并具体回应其他答案(结构)中的错误观点:

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

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

其他提示

RFC7232 更新RFC2616地说:

  

在服务器产生一个304响应必须产生任何的      这会在200(OK)被送到下面的头字段      响应于相同的请求:缓存控制,内容位置,日期      ETag的,过期,和变化。

如果我理解正确的话,那么浏览器实际上缓存了 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 专门请求该文件(或者除非您有一个自定义应用程序以某种方式控制该功能)。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top