“缓存控制:max-age=0,无缓存"但浏览器绕过服务器查询(并命中缓存)? [英] "Cache-Control: max-age=0, no-cache" but browser bypasses server query (and hits cache)?

查看:44
本文介绍了“缓存控制:max-age=0,无缓存"但浏览器绕过服务器查询(并命中缓存)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Chrome 40(非常漂亮和现代).

Cache-Control: max-age=0, no-cache 已在所有页面上设置 - 所以我希望浏览器仅在首先与服务器检查并得到 304 Not Modified 响应.

但是,在按下后退按钮时,浏览器会愉快地访问自己的缓存,而不需要与服务器进行检查.

如果我打开同一个页面,就像我使用后退按钮到达的那样,在一个新选项卡中,它会检查服务器(并在事情发生变化时得到 303 See Other 响应).

请参阅下面的屏幕截图,其中显示了 Chrome 开发者工具的网络"选项卡中两种不同情况的输出.

我想我可以使用 max-age=0, no-cache 作为 no-store 的更轻量级的替代品,我不希望用户看到陈旧的数据通过后退按钮(但数据是无价值的,因此可以缓存).

我对 no-cache 的理解(参见

<块引用>

无缓存

如果 no-cache 指令未指定字段名称,则缓存不得使用响应来满足后续请求,而无需与源服务器成功重新验证.这允许源服务器阻止缓存,即使缓存已配置为向客户端请求返回陈旧响应.

如果 no-cache 指令确实指定了一个或多个字段名称,那么缓存可以使用响应来满足后续请求,但受缓存的任何其他限制.但是,如果没有与源服务器成功重新验证,则不得在对后续请求的响应中发送指定的字段名.这允许源服务器防止在响应中重复使用某些标头字段,同时仍然允许缓存响应的其余部分.

除了顾名思义,no-cache 并不要求响应一定不能存储在缓存中.它只指定缓存的响应在没有重新验证的情况下不得重用于后续请求,因此它是 must-revalidate, max-age=0 的简写.

什么是后续请求取决于浏览器,而我的理解是使用后退按钮没有.这种行为因不同的浏览器引擎而异.

no-store 禁止对所有请求使用缓存的响应,而不仅仅是后续请求.

请注意,即使使用 no-store,RFC 实际上也允许客户端存储响应以在历史缓冲区中使用.这意味着即使指定了 no-store,客户端仍然可以使用缓存的响应.

后一种行为涵盖页面已在浏览器历史记录中记录其原始页面标题的情况.另一个用例是各种移动浏览器的行为,它们不会丢弃前一页,直到下一个页面完全加载,因为用户可能想要中止.

为了澄清后退按钮的行为:它不受任何缓存头的影响,根据 http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13

<块引用>

用户代理通常具有历史机制,例如返回";按钮和历史列表,可用于重新显示之前在会话中检索到的实体.

历史机制和缓存是不同的.特别是历史机制不应该尝试显示资源当前状态的语义透明视图.相反,历史机制旨在准确显示用户在检索资源时所看到的内容.

默认情况下,过期时间不适用于历史机制.如果实体仍在存储中,即使实体已过期,历史机制也应该显示它,除非用户已专门配置代理以刷新过期的历史文档.

这意味着在使用后退按钮时不尊重任何缓存控制标头是推荐的行为.如果您的浏览器碰巧遵守了回溯的到期日期,或者将 no-store 指令不仅应用于浏览器缓存而且还应用于历史记录,那么它实际上已经偏离了该建议.

解决方法:
你不能,也不应该这样做.如果用户返回之前访问过的页面,大多数浏览器甚至会尝试恢复视口.如果这是用户离开页面之前的原始行为,您可以使用 AJAX 等延迟机制来刷新内容,否则您甚至不应该修改内容.

I'm using Chrome 40 (so something nice and modern).

Cache-Control: max-age=0, no-cache is set on all pages - so I expect the browser to only use something from its cache if it has first checked with the server and gotten a 304 Not Modified response.

However on pressing the back button the browser merrily hits its own cache without checking with the server.

If I open the same page, as I reached with the back button, in a new tab then it does check with the server (and gets a 303 See Other response as things have changed).

See the screen captures below showing the output for the two different cases from the Network tab of the Chrome Developer Tools.

I thought I could use max-age=0, no-cache as a lighter weight alternative to no-store where I don't want users seeing stale data via the back button (but where the data is non-valuable and so can be cached).

My understanding of no-cache (see here and here on SO) is that the browser must always revalidate all responses. So why doesn't Chrome do this when using the back button?

Is no-store the only option?


200 response (from cache) on pressing back button:

303 response on requesting the same page in a new tab:

解决方案

From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1

no-cache

If the no-cache directive does not specify a field-name, then a cache MUST NOT use the response to satisfy a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent caching even by caches that have been configured to return stale responses to client requests.

If the no-cache directive does specify one or more field-names, then a cache MAY use the response to satisfy a subsequent request, subject to any other restrictions on caching. However, the specified field-name(s) MUST NOT be sent in the response to a subsequent request without successful revalidation with the origin server. This allows an origin server to prevent the re-use of certain header fields in a response, while still allowing caching of the rest of the response.

Other than the name implies, no-cache does not require that the response must not be stored in cache. It only specifies that the cached response must not be reused to serve a subsequent request without re-validating, so it's a shorthand for must-revalidate, max-age=0.

It is up to the browser what to qualify as a subsequent request, and to my understanding using the back-button does not. This behavior varies between different browser engines.

no-store forbids the use of the cached response for all requests, not only for subsequent ones.

Note that even with no-store, the RFC actually permits the client to store the response for use in history buffers. That means client may still use a cached response even when no-store has been specified.

Latter behavior covers cases where the page has been recorded with its original page title in the browser history. Another use case is the behavior of various mobile browsers which will not discard the previous page until the following page has fully loaded as the user might want to abort.

For clarification on the the behavior of the back button: It is not subject to any cache header, according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13

User agents often have history mechanisms, such as "Back" buttons and history lists, which can be used to redisplay an entity retrieved earlier in a session.

History mechanisms and caches are different. In particular history mechanisms SHOULD NOT try to show a semantically transparent view of the current state of a resource. Rather, a history mechanism is meant to show exactly what the user saw at the time when the resource was retrieved.

By default, an expiration time does not apply to history mechanisms. If the entity is still in storage, a history mechanism SHOULD display it even if the entity has expired, unless the user has specifically configured the agent to refresh expired history documents.

That means that disrespecting any cache control headers when using the back button is the recommended behavior. If your browser happens to honor a backdated expiration date or applies the no-store directive not only to the browser cache but also to the history, it's actually already departing from that recommendation.

For how to solve it:
You can't, and you are not supposed to. If the user is returning to a previously visited page, most browsers will even try to restore the viewport. You may use deferred mechanism like AJAX to refresh content if this was the original behavior before the user left the page, but otherwise you should not even modify the content.

这篇关于“缓存控制:max-age=0,无缓存"但浏览器绕过服务器查询(并命中缓存)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆