为什么 HTTP 响应中应该同时使用 no-cache 和 no-store ?
我被告知要防止用户信息泄漏,仅响应“无缓存”是不够的。 “无店”也是必要的。
Cache-Control: no-cache, no-store
阅读本规范后 http://www.w3.org/Protocols/rfc2616/rfc2616 -sec14.html,我仍然不太清楚为什么。
我目前的理解是它只是针对中间缓存服务器。 即使响应“无缓存”,中间缓存服务器仍然可以将内容保存到非易失性存储中。 中间缓存服务器将决定是否将保存的内容用于后续请求。 但是,如果响应中包含“no-store”,则中间缓存服务器不应存储该内容。 所以,它更安全。
还有其他原因我们需要“无缓存”和“无存储”吗?
I'm told to prevent user-info leaking, only "no-cache" in response is not enough. "no-store" is also necessary.
Cache-Control: no-cache, no-store
After reading this spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, I'm still not quite sure why.
My current understanding is that it is just for intermediate cache server. Even if "no-cache" is in response, intermediate cache server can still save the content to non-volatile storage. The intermediate cache server will decide whether using the saved content for following request. However, if "no-store" is in the response, the intermediate cache sever is not supposed to store the content. So, it is safer.
Is there any other reason we need both "no-cache" and "no-store"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
我必须澄清,
no-cache
并不意味着不缓存。 事实上,这意味着在每次请求时使用您可能拥有的任何缓存响应之前“通过服务器重新验证”。另一方面,
must-revalidate
仅在资源被视为过时时才需要重新验证。如果服务器说该资源仍然有效,则缓存可以以其表示形式进行响应,从而减轻服务器重新发送整个资源的需要。
no-store
实际上是完整的不缓存指令,旨在防止以任何形式的缓存存储表示。我说什么都可以,但请注意 RFC 2616 HTTP 规范中的这一点:
,但这在较新的 RFC 7234 HTTP 规范中被省略,可能是为了使
no-store
更强,请参阅:https://www.rfc-editor.org/rfc/rfc7234#section-5.2.1.5
I must clarify that
no-cache
does not mean do not cache. In fact, it means "revalidate with server" before using any cached response you may have, on every request.must-revalidate
, on the other hand, only needs to revalidate when the resource is considered stale.If the server says that the resource is still valid then the cache can respond with its representation, thus alleviating the need for the server to resend the entire resource.
no-store
is effectively the full do not cache directive and is intended to prevent storage of the representation in any form of cache whatsoever.I say whatsoever, but note this in the RFC 2616 HTTP spec:
But this is omitted from the newer RFC 7234 HTTP spec in potentially an attempt to make
no-store
stronger, see:https://www.rfc-editor.org/rfc/rfc7234#section-5.2.1.5
在某些情况下,即使响应标头中包含
Cache-Control: no-cache
,IE6 仍会缓存文件。无缓存
的 W3C 状态< /a>:在我的应用程序中,如果您访问带有
no-cache
标头的页面,然后注销并在浏览器中返回,IE6 仍会从缓存中获取该页面(无需新的/验证请求)到服务器)。 添加no-store
标头会阻止它这样做。 但如果你相信 W3C 的话,实际上没有办法控制这种行为:浏览器历史记录和普通 HTTP 缓存之间的一般差异在具体描述中进行了描述。规范的子部分。
Under certain circumstances, IE6 will still cache files even when
Cache-Control: no-cache
is in the response headers.The W3C states of
no-cache
:In my application, if you visited a page with the
no-cache
header, then logged out and then hit back in your browser, IE6 would still grab the page from the cache (without a new/validating request to the server). Adding in theno-store
header stopped it doing so. But if you take the W3C at their word, there's actually no way to control this behavior:General differences between browser history and the normal HTTP caching are described in a specific sub-section of the spec.
在正常情况下,
no-store
不是必需的,并且在某些情况下可能会损害速度和可用性。它的目的是作为一种隐私措施:它告诉浏览器和缓存,响应包含敏感信息,这些信息永远不应写入基于磁盘的缓存(或其他非易失性存储)。
工作原理:
通常,即使服务器将响应标记为
无缓存
,用户代理(例如浏览器)也可能会存储该响应。 如果用户代理稍后需要再次请求相同的资源,它可能会发出一个条件请求,服务器可以决定发送更新的响应或允许用户代理重新使用存储的响应。如果服务器没有肯定地确认存储的响应仍然可以使用,或者如果无法到达服务器,则用户代理(例如浏览器)无法使用存储的响应。
使用
no-store
将阻止该响应存储到磁盘或任何非易失性存储中,并阻止该响应在以后的条件请求中使用。这是不正确的。 与 HTTP 1.1 兼容的中间缓存服务器将遵循与浏览器缓存相同的
no-cache
和must-revalidate
指令。如果中间缓存服务器不支持 HTTP 1.1,那么您将需要使用
Pragma: no-cache
并希望得到最好的结果。 请注意,如果它不支持 HTTP 1.1,则no-store
也不会达到预期的效果。no-store
should not be necessary in normal situations, and in some cases can harm speed and usability.It was intended as a privacy measure: it tells browsers and caches that the response contains sensitive information that should never be written to a disk-based cache (or other non-volatile storage).
How it works:
Normally, even if a response is marked as
no-cache
by the server, a user agent such as a browser may store the response. If the user agent needs to request the same resource again later, it may make a conditional request whereby the server can decide to either send an updated response or allow the user agent to re-use the stored response.If the server does not positively affirm that the stored response can still be used, or if the server can't be reached, the user agent (eg the browser) can't use the stored response.
Using
no-store
will prevent that response being stored to disk or any non-volatile storage, and prevents the response being used in a later conditional request.This is incorrect. Intermediate cache servers compatible with HTTP 1.1 will obey the same
no-cache
andmust-revalidate
instructions as browser caches will.If the intermediate cache server does not support HTTP 1.1, then you will need to use
Pragma: no-cache
and hope for the best. Note that if it doesn't support HTTP 1.1 thenno-store
is also not going to have the desired effect.来自 HTTP 1.1 规范:
From the HTTP 1.1 specification:
如果您想阻止所有缓存(例如,使用后退按钮时强制重新加载),您需要:
no-cache for IE
no-store for Firefox
这里有我关于此的信息:
http://blog.httpwatch.com/2008/10/15/two-important-differences- Between-firefox-and-ie-caching/
If you want to prevent all caching (e.g. force a reload when using the back button) you need:
no-cache for IE
no-store for Firefox
There's my information about this here:
http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/
对于 Chrome,无缓存用于在重新访问时重新加载页面,但如果您返回历史记录(后退按钮),它仍然会缓存它。 要重新加载页面以进行历史记录返回,请使用 no-store。 IE 需要必须重新验证才能在所有情况下工作。
因此,为了确保避免所有错误和误解,
如果我想确保它重新加载,我总是使用它。
For chrome, no-cache is used to reload the page on a re-visit, but it still caches it if you go back in history (back button). To reload the page for history-back as well, use no-store. IE needs must-revalidate to work in all occasions.
So just to be sure to avoid all bugs and misinterpretations I always use
if I want to make sure it reloads.
如果缓存系统正确实现了无存储,那么您就不需要无缓存。 但并非所有人都这样做。 此外,一些浏览器像无存储一样实现无缓存。 因此,虽然没有严格要求,但同时包含两者可能是最安全的。
If a caching system correctly implements no-store, then you wouldn't need no-cache. But not all do. Additionally, some browsers implement no-cache like it was no-store. Thus, while not strictly required, it's probably safest to include both.
请注意,当尝试下载通过 https 提供的文件并且服务器发送
Cache-Control: no-cache
或Pragma: no-cache 时,Internet Explorer 从版本 5 到 8 将抛出错误
标头。请参阅http://support.microsoft.com/kb/812935/en-us
使用
Cache-Control: no-store
和Pragma: private
似乎是仍然有效的最接近的方法。Note that Internet Explorer from version 5 up to 8 will throw an error when trying to download a file served via https and the server sending
Cache-Control: no-cache
orPragma: no-cache
headers.See http://support.microsoft.com/kb/812935/en-us
The use of
Cache-Control: no-store
andPragma: private
seems to be the closest thing which still works.最初我们多年前使用了无缓存,并且确实在某些浏览器上遇到了一些陈旧内容的问题......不幸的是不记得具体细节了。
从那时起,我们就决定只使用无存储。 从那时起,任何浏览器或中介机构都不再回顾过时内容,也没有遇到过任何过时内容的问题。
这个空间肯定是由实际的实现与各种 RFC 中所写的内容主导的。 许多代理人尤其倾向于认为,通过用自己的政策取代他们应该遵循的政策,他们可以更好地“提高绩效”。
Originally we used no-cache many years ago and did run into some problems with stale content with certain browsers... Don't remember the specifics unfortunately.
We had since settled on JUST the use of no-store. Have never looked back or had a single issue with stale content by any browser or intermediaries since.
This space is certainly dominated by reality of implementations vs what happens to have been written in various RFCs. Many proxies in particular tend to think they do a better job of "improving performance" by replacing the policy they are supposed to be following with their own.
为了回答这个问题,这里有两个参与者,客户端(请求)和服务器(响应)。
客户端:
客户端只能使用一种缓存方法进行请求。 有不同的方法,如果没有指定,将使用
默认
。注意:
age
处于stale-while-revalidate
生命周期内。 它需要“重新验证”,但仍然可以接受退货。“带条件获取
If-Modified-Since
或ETag
,以便服务器可以响应304:(未修改)
。https://fetch.spec.whatwg.org/#concept-request-缓存模式
服务器::
现在我们了解了客户端可以做什么,服务器响应就更有意义了。
查看
Cache-Control
标头,如果服务器返回:现在我们可以将它们放在一起。 这意味着唯一的可能性是:
客户端或服务器的任何组合都可以指定要使用的方法或方法集。 如果服务器返回
no-store
,则无论客户端请求类型是什么,它都不会访问缓存。 如果客户端请求是no-store
,那么无论服务器返回什么,它都不会缓存。 如果客户端未指定请求类型,服务器将使用 Cache-Control 来指定它。服务器同时返回
no-cache
和no-store
是没有意义的,因为no-store
会覆盖所有内容。 是的,您可能已经同时看到过两者,并且在损坏的浏览器实现之外它毫无用处。 尽管如此,no-store
自 1999 年以来一直是规范的一部分:https://datatracker.ietf.org/doc/html/rfc2616#section-14.9.2在实际使用中,如果您的服务器支持
304:未修改
,如果您想使用客户端缓存来提高速度,但仍想强制进行网络获取,请使用no-cache
。 如果不支持304
,并且想要强制网络获取,请使用no-store
。 如果有时您对缓存没问题,请使用新鲜度和重新验证标头。实际上,如果您在客户端上混合使用
no-cache
和no-store
,几乎不会有任何改变。 然后,只需发送几个标头,浏览器就会处理不同的内部响应。 如果您使用no-cache
,然后忘记使用它,则可能会出现问题。no-cache
告诉它将响应存储在缓存中,稍后没有它的请求可能会触发内部缓存。有时,您甚至可能希望根据上下文在同一资源上混合使用方法。 例如,您可能希望在服务工作线程和后台同步上使用
reload
,但对网页本身使用default
。 您可以在此处根据自己的喜好操作用户代理(浏览器)缓存。 请记住,服务器通常对缓存如何工作有最终决定权。澄清一些未来可能出现的混乱。 客户端可以在请求上使用
Cache-Control
标头,告诉服务器在响应时不要使用自己的缓存系统。 这与浏览器/服务器动态无关,更多地与服务器/数据库动态相关。另外,“无存储”在技术上意味着不得存储到任何非易失性存储(磁盘)并尽快从易失性存储(内存)中释放它。 实际上,这意味着根本不使用缓存。 该命令实际上是双向的。 带有
no-store
的客户端请求不应写入磁盘或数据库,并且是瞬态的。TL;DR:
no-store
覆盖no-cache
。 设置两者是没有用的,除非我们谈论的是不符合规范或不支持no-store
的 HTTP/1.0 浏览器(也许是 IE11?)。 使用no-cache
来支持304
。To answer the question, there are two players here, the client (request) and the server (response).
Client:
The client can only request with ONE cache method. There are different methods and if not specified, will use
default
.Notes:
age
is within thestale-while-revalidate
lifetime. It needs "revalidation", but is still acceptable to return.fetch".
If-Modified-Since
, orETag
so the server can respond with304: (Not Modified)
.https://fetch.spec.whatwg.org/#concept-request-cache-mode
Server::
Now that we understand what the client can do, the server responses make more sense.
Looking at the
Cache-Control
header, if the server returns:Now we can put it all together. That means the only possibilities are:
Any combination of client, or server can dictate what method, or set of methods, to use. If the server returns
no-store
, it's not going to hit the cache, no matter what the client request type. If the client request wasno-store
, it doesn't matter what the server returns, it won't cache. If the client doesn't specify a request type, the server will dictate it withCache-Control
.It makes no sense for a server to return both
no-cache
andno-store
sinceno-store
overrides everything. Yes, you've probably seen both together, and it's useless outside of broken browser implementations. Still,no-store
has been part of spec since 1999: https://datatracker.ietf.org/doc/html/rfc2616#section-14.9.2In real life usage, if your server supports
304: Not Modified
, and you want to use client cache as a way to improve speed, but still want to force a network fetch, useno-cache
. If don't support304
, and want to force a network fetch, useno-store
. If you're okay with cache sometimes, use freshness and revalidation headers.In reality, if you're mixing up
no-cache
andno-store
on the client, very little would change. Then, just a couple of headers get sent and there will different internal responses handled by the browser. An issue can occur if you useno-cache
and then forget to use it later.no-cache
tells it to store the response in the cache, and a later request without it might trigger internal cache.There are times when you may want to mix methods even on the same resource based on context. For example, you may want to use
reload
on a service worker and background sync, but usedefault
for the web page itself. This is where you can manipulate the user agent (browser) cache to your liking. Just remember that the server generally has the final say as to how the cache should work.To clarify some possible future confusion. The client can use the
Cache-Control
header on the request, to tell the server to not use its own cache system when responding. This is unrelated to the browser/server dynamic, and more about the server/database dynamic.Also
no-store
technically means must not store to any non-volatile storage (disk) and release it from volatile storage (memory) ASAP. In practice, it means don't use a cache at all. The command actually goes both ways. A client request withno-store
shouldn't write to disk or database and is meant to transient.TL;DR:
no-store
overridesno-cache
. Setting both is useless, unless we are talking out-of-spec or HTTP/1.0 browsers that don't supportno-store
(Maybe IE11?). Useno-cache
for304
support.更糟糕的是,在某些情况下,不能使用 no-cache,但 no-store 可以:
http://faindu.wordpress.com/2008/04/18/ie7-ssl-xml-flex-error-2032-stream -错误/
Just to make things even worse, in some situations, no-cache can't be used, but no-store can:
http://faindu.wordpress.com/2008/04/18/ie7-ssl-xml-flex-error-2032-stream-error/
这是一个相当古老的主题,但我将分享一些最近的想法:
no-store
:不得尝试存储任何内容,并且还必须采取措施删除它可能拥有的任何副本。no-cache
:在未先与源服务器进行验证的情况下,切勿使用本地副本。 它可以防止缓存命中的所有可能性,即使使用新资源也是如此。所以,回答这个问题,只使用其中之一就足够了。
此外,一些(不是非常)最近的作品证明浏览器更如今与缓存控制兼容。
A pretty old topic but I'll share some recent ideas:
no-store
: Must not attempt to store anything, and must also take action to delete any copy it might have.no-cache
: Never use a local copy without first validating with the origin server. It prevents all possibility of a cache hit, even with fresh resources.So, answering the question, using only one of them is enough.
Also, some (not very) recent works prove that browsers are more Cache-Control compatible nowadays.
OWASP 对此进行了讨论:
来源此处 。
OWASP discusses this:
Source here.