简体   繁体   English

http缓存应该如何工作?

[英]How should http cache actually work?

I know this is actually a old thing but I really got questions about this and how it was supposed to work when it started. 我知道这实际上是一件旧事,但我真的对此有疑问,以及它在启动时应该如何工作。 So I got at least these four important cache headers I can send back to the client ( Last-Modified , Cache-Control , Expires and ETag ) 所以我至少得到了这四个重要的缓存头,我可以发送回客户端( Last-ModifiedCache-ControlExpiresETag

Example situation for question 2.2: 问题2.2的示例情况:

So let's say I got some site with articles. 所以,假设我有一些文章。 There might be a new article every 15 minutes to 7 days. 每15分钟到7天可能会有一篇新文章。 So I set Cache-Control and Expires to cache for 15 min so the client always got the newest version of it. 因此,我将Cache-ControlExpires为缓存15分钟,以便客户端始终获得最新版本。

What I think about ETag and Last-Modified at the moment: 我对ETagLast-Modified看法:

I just put some hash of the content in there and I can send the client 304 if If-None-Match == ETag . 我只是在那里放了一些内容的哈希值,如果If-None-Match == ETag ,我可以发送客户端304

I can send the client 304 if If-Modified-Since >= Last-Modified . 如果If-Modified-Since > = Last-Modified我可以发送客户端304

Questions 问题

  1. Do I need Cache-Control and Expires to support all browsers or not ? 我是否需要Cache-Control Expires来支持所有浏览器?
  2. It looks like Cache-Control and Expires only tells my browser how long the content should be cached on the computer right? 它看起来像Cache-ControlExpires只告诉我的浏览器应该在计算机上缓存内容多长时间?
    • So I can only use ETag and Last-Modified to find out when I should send 304 right? 所以我只能使用ETagLast-Modified来找出我应该发送304权利吗?
    • So I could just set Cache-Control and Expires to forever and just send the client the new version if ETag or Last-Modified changed that? 所以我可以将Cache-ControlExpires为永远,如果ETagLast-Modified改变了那么只是向客户端发送新版本?
      • Because this works in my browser but will this work in all browsers? 因为这适用于我的浏览器,但这适用于所有浏览器吗?
  3. Do I need ETag and Last-Modified to support all browsers or not ? 我是否需要ETag Last-Modified才能支持所有浏览器?
  4. Pragma looks like another cache header similar to Cache-Control , which browsers are using Pragma and do I need it? Pragma看起来像另一个类似于Cache-Control缓存头,浏览器使用的是Pragma ,我需要它吗?

Do I need Cache-Control and Expires to support all browsers or not ? 我是否需要Cache-ControlExpires来支持所有浏览器?

Cache-Control is introduced in HTTP 1.1 and hence only supported on clients supporting HTTP 1.1. Cache-Control在HTTP 1.1中引入,因此仅在支持HTTP 1.1的客户端上受支持。 Expires is supported since HTTP 1.0. 自HTTP 1.0起支持Expires If both are specified, then Cache-Control takes precedence and Expires is ignored altogether. 如果同时指定了两者,则Cache-Control优先,并且完全忽略Expires


It looks like Cache-Control and Expires only tells my browser how long the content should be cached on the computer right? 它看起来像Cache-ControlExpires只告诉我的浏览器应该在计算机上缓存内容多长时间?

Basically, yes. 基本上,是的。 If the Cache-Control is absent (and thus Expires will be used) or set right with max-age . 如果Cache-Control不存在(因此将使用Expires )或者使用max-age


So I can only use ETag and Last-Modified to find out when I should send 304 right? 所以我只能使用ETagLast-Modified来找出我应该发送304的权利吗?

Here, your question starts to be confusing. 在这里,你的问题开始令人困惑。 You actually need to check If-None-Match and If-Modified-Since headers for that. 实际上,您需要检查If-None-MatchIf-Modified-Since标头。 Usually, browser sends only one of them on a conditional GET request and if it matches with the current value of ETag or Last-Modified in the server, then return 304 along with the ETag header. 通常,浏览器只在条件GET请求中发送其中一个,如果它与服务器中ETagLast-Modified的当前值匹配,则返回304和ETag标头。 Note that if browser sends them both for some reason, then you can just ignore If-Modified-Since . 请注意,如果浏览器出于某种原因发送它们,那么您可以忽略If-Modified-Since


So I could just set Cache-Control and Expires to forever and just send the client the new version if ETag or Last-Modified changed that? 所以我可以将Cache-ControlExpires为永远,如果ETagLast-Modified改变了那么只是向客户端发送新版本?

No. If you set it to forever, the client will never send a (conditional) request until the enduser pressed (Ctrl)+F5. 不。如果您将其设置为永久,客户端将永远不会发送(条件)请求,直到最终用户按下(Ctrl)+ F5。 You need to set the Cache-Control: max-age or Expires to the desired cache time (to 15 minutes in the future maybe?). 您需要将Cache-Control: max-ageExpires设置为所需的缓存时间(将来可能是15分钟?)。


Because this works in my browser but will this work in all browsers? 因为这适用于我的浏览器,但这适用于所有浏览器吗?

Watch out how you test: pressing F5 will always send a conditional GET request. 注意你的测试方法:按F5将始终发送有条件的GET请求。 But a simple page-to-page navigation and form submits (like as in real world) won't send a conditional GET request! 但是一个简单的页面到页面导航和表单提交(就像在现实世界中一样)将不会发送有条件的GET请求! Pressing Ctrl+F5 will ignore the cache and send a brand new GET request. 按Ctrl + F5将忽略缓存并发送全新的GET请求。


Do I need ETag and Last-Modified to support all browsers or not ? 我是否需要ETag和Last-Modified才能支持所有浏览器?

All browsers support both. 所有浏览器都支持。 Browsers are required to send ETag back via If-None-Match if it has been received from the server and browser needs to perform a conditional GET request. 如果已经从服务器接收到浏览器并且浏览器需要执行条件GET请求,则浏览器需要通过If-None-Match发回ETag。 The Last-Modified is for them optional and usually only sent if ETag is absent on the resource. Last-Modified对于它们是可选的,并且通常仅在资源上不存在ETag时才发送。 See also RFC 2616 section 13.3.4 . 另见RFC 2616第13.3.4节


Pragma looks like another cache header similar to Cache-Control, which browsers are using Pragma and do I need it? Pragma看起来像另一个类似于Cache-Control的缓存头,浏览器使用的是Pragma,我需要它吗?

You don't need it if you want to cache. 如果要缓存,则不需要它。 You only need it if you want to not cache (in order to cover HTTP 1.0 clients/proxies, whose population is currently steadily decreasing, though). 如果你想缓存(为了掩盖HTTP 1.0客户端/代理服务器,它的人口目前稳步下降,虽然)你只需要它。


If you're familiar with Java, or can at least decipher it, then you may find this article helpful: FileServiet supporting resume and caching and GZIP . 如果您熟悉Java,或者至少可以解密它,那么您可能会发现本文很有用: FileServiet支持简历和缓存以及GZIP

See also: 也可以看看:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM