apache 上次修改的缓存过期控制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/562802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cache Expire Control with Last Modification
提问by David Z
In Apache's mod_expiresmodule, there is the Expiresdirective with two base time periods, access, and modification.
在 Apache 的mod_expires模块中,有Expires两个基本时间段的指令,访问和修改。
ExpiresByType text/html "access plus 30 days"
understandably means that the cache will request for fresh content after 30 days.
可以理解的是,缓存将在 30 天后请求新内容。
However,
然而,
ExpiresByType text/html "modification plus 2 hours"
doesn't make intuitive sense.
没有直观的意义。
How does the browser cache know that the file has been modified unless it makes a request to the server? And if it is making a call to the server, what is the use of caching this directive? It seems to me that I am not understanding some crucial part of caching. Please enlighten me.
除非向服务器发出请求,否则浏览器缓存如何知道文件已被修改?如果它正在调用服务器,缓存这个指令有什么用?在我看来,我不了解缓存的某些关键部分。请赐教。
回答by David Z
An Expires*directive with "modification" as its base refers to the modification time of the file on the server. So if you set, say, "modification plus 2 hours", any browser that requests content within 2 hours after the file is modified (on the server) will cache that content until 2 hours after the file's modification time. And the browser knows when that time is because the server sends an Expiresheader with the proper expiration time.
Expires*以“修改”为基础的指令是指服务器上文件的修改时间。因此,如果您设置,例如,“修改加 2 小时”,则在文件修改后 2 小时内(在服务器上)请求内容的任何浏览器都将缓存该内容,直到文件修改时间后 2 小时。浏览器知道那个时间是什么时候,因为服务器发送了一个Expires具有正确过期时间的标头。
Let me explain with an example: say your Apache configuration includes the line
让我用一个例子来解释:说你的 Apache 配置包括这行
ExpiresDefault modification plus 2 hours
and you have a file index.html, which the ExpiresDefaultdirective applies to, on the server. Suppose you upload a version of index.htmlat 9:53 GMT, overwriting the previous existing index.html(if there was one). So now the modification time of index.htmlis 9:53 GMT. If you were running ls -lon the server (or diron Windows), you would see it in the listing:
并且您在服务器上有一个文件index.html,该ExpiresDefault指令适用于该文件。假设您index.html在格林威治标准时间 9:53上传了一个版本,覆盖了之前的现有版本index.html(如果有的话)。所以现在修改时间index.html是格林威治标准时间9:53。如果您ls -l在服务器(或dirWindows)上运行,您会在列表中看到它:
-rw-r--r-- 1 apache apache 4096 Feb 18 09:53 index.html
Now, with every request, Apache sends the Last-Modifiedheader with the last modification time of the file. Since you have that ExpiresDefaultdirective, it will also send the Expiresheader with a time equal to the modification time of the file (9:53) plus two hours. So here is part of what the browser sees:
现在,对于每个请求,Apache 都会发送包含Last-Modified文件最后修改时间的标头。由于您有该ExpiresDefault指令,它还会发送Expires标头,其时间等于文件的修改时间 (9:53) 加上两个小时。所以这是浏览器看到的部分内容:
Last-Modified: Wed, 18 Feb 2009 09:53:00 GMT
Expires: Wed, 18 Feb 2009 11:53:00 GMT
If the time at which the browser makes this request is before 11:53 GMT, the browser will cache the page, because it has not yet expired. So if the user first visits the page at 11:00 GMT, and then goes to the same page again at 11:30 GMT, the browser will see that its cached version is still valid and will not (or rather, is allowed not to) make a new HTTP request.
如果浏览器发出此请求的时间在格林威治标准时间 11:53 之前,浏览器将缓存该页面,因为它尚未过期。因此,如果用户在格林威治标准时间 11:00 首次访问该页面,然后在格林威治标准时间 11:30 再次访问同一页面,浏览器将看到其缓存版本仍然有效并且不会(或者更确切地说,允许不) 发出新的 HTTP 请求。
If the user goes to the page a third time at 12:00 GMT, the browser sees that its cached version has now expired (it's after 11:53) so it attempts to validate the page, sending a request to the server with a If-Modified-Since header. A 304 (not modified) response with no body will be returned since the page's date has not been altered since it was first served. Since the expiry date has passed -- the page is 'stale' -- a validation request will be made every subsequent time the page is visited until validation fails.
如果用户在格林威治标准时间 12:00 第三次访问该页面,浏览器会看到其缓存版本现已过期(11:53 之后),因此它尝试验证该页面,并使用 If 向服务器发送请求-Modified-Since 标头。将返回没有正文的 304(未修改)响应,因为该页面的日期自首次提供以来尚未更改。由于过期日期已过——页面已“陈旧”——每次访问页面时都会发出验证请求,直到验证失败。
Now, let's pretend instead that you uploaded a new version of the page at 11:57. In this case, the browser's attempt to validate the old version of the page at 12:00 fails and it receives in the response, along with the new page, these two new headers:
现在,让我们假设您在 11:57 上传了页面的新版本。在这种情况下,浏览器在 12:00 尝试验证页面的旧版本失败,它在响应中接收到新页面以及这两个新标头:
Last-Modified: Wed, 18 Feb 2009 11:57:00 GMT
Expires: Wed, 18 Feb 2009 13:57:00 GMT
(The last modification time of the file becomes 11:57 upon upload of the new version, and Apache calculates the expiration time as 11:57 + 2:00 = 13:57 GMT.)
(新版本上传后文件最后修改时间为11:57,Apache计算过期时间为11:57 + 2:00 = 13:57 GMT。)
Validation (using the more recent date) will not be required now until 13:57.
现在直到 13:57 才需要验证(使用最近的日期)。
(Note of course that many other things are sent along with the two headers I listed above, I just trimmed out all the rest for simplicity)
(当然,请注意,许多其他内容与我上面列出的两个标题一起发送,为了简单起见,我只修剪了所有其他内容)
回答by Andrew Vit
The server sends a header such as: "Last-Modified: Wed, 18 Feb 2009 00:00:00 GMT". The cache behaves based on either this header or the access time.
服务器发送一个标头,例如:“ Last-Modified: Wed, 18 Feb 2009 00:00:00 GMT”。缓存的行为基于此标头或访问时间。
Say if the content is expected to be refreshed every day, then you want it to expire "modification plus 24 hours".
假设内容希望每天刷新,那么您希望它过期“修改加 24 小时”。
If you don't know when the content will be refreshed, then it's better to base it on the access time.
如果你不知道什么时候会刷新内容,那么最好根据访问时间来确定。
回答by NilObject
My understanding is that modification asks the browser to base the cache time based on the Last-Modificatied HTTP header's value. So, modification plus 2 hours would be the Last-Modificatied time + 2 hours.
我的理解是修改要求浏览器根据 Last-Modificatied HTTP 标头的值来确定缓存时间。因此,修改加上 2 小时将是上次修改时间 + 2 小时。
回答by William Holt
First of all, thanks to David Z for the detailed explanation above. In answer to bushman's question about why does it make sense to invoke caching if the server is still required to make a request, the answer is that the time is saved in what is returned by the server. If the cache directives indicate that a file's content is still fresh, instead of returning content, a 304 code is returned with an empty response body. That is where the time is saved.
首先感谢David Z上面的详细解释。在回答布什曼关于如果仍然需要服务器发出请求的情况下调用缓存为什么有意义的问题时,答案是时间被保存在服务器返回的内容中。如果缓存指令指示文件的内容仍然是新鲜的,而不是返回内容,则返回 304 代码和空响应正文。这就是节省时间的地方。
A better explanation than I've given is here, from https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers:
比我给出的更好的解释在这里,来自https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers:
Though conditional requests do invoke a call across the network, unmodified resources result in an empty response body – saving the cost of transferring the resource back to the end client. The backend service is also often able to very quickly determine a resource's last modified date without accessing the resource which itself saves non-trivial processing time.
Time-based
A time-based conditional request ensures that only if the requested resource has changed since the browser's copy was cached will the contents be transferred. If the cached copy is the most up-to-date then the server returns the 304 response code.
To enable conditional requests the application specifies the last modified time of a resource via the Last-Modified response header.
Cache-Control:public, max-age=31536000 Last-Modified: Mon, 03 Jan 2011 17:45:57 GMT
The next time the browser requests this resource it will only ask for the contents of the resource if they're unchanged since this date using the If-Modified-Since request header
If-Modified-Since: Mon, 03 Jan 2011 17:45:57 GMT
If the resource hasn't changed since Mon, 03 Jan 2011 17:45:57 GMT the server will return with an empty body with the 304 response code.
尽管条件请求确实会通过网络调用调用,但未修改的资源会导致响应主体为空——从而节省了将资源传输回终端客户端的成本。后端服务通常还能够非常快速地确定资源的上次修改日期,而无需访问资源本身,从而节省了大量的处理时间。
基于时间
基于时间的条件请求确保仅当请求的资源自浏览器的副本被缓存以来发生更改时,才会传输内容。如果缓存的副本是最新的,则服务器返回 304 响应代码。
为了启用条件请求,应用程序通过 Last-Modified 响应头指定资源的最后修改时间。
Cache-Control:public, max-age=31536000 上次修改时间:2011 年 1 月 3 日星期一 17:45:57 GMT
下一次浏览器请求此资源时,它只会使用 If-Modified-Since 请求标头,如果自此日期以来没有更改,则只询问资源的内容
If-Modified-Since: 2011 年 1 月 3 日星期一 17:45:57 GMT
如果资源自格林威治标准时间 2011 年 1 月 3 日星期一 17:45:57 起没有改变,服务器将返回一个带有 304 响应代码的空主体。

