Apache 上次修改的缓存过期控制

Apache 上次修改的缓存过期控制,apache,caching,browser,mod-expires,Apache,Caching,Browser,Mod Expires,在Apache的mod_expires模块中,有expires指令,有两个基本时间段,access和modification ExpiresByType text/html "access plus 30 days" 可以理解,这意味着缓存将在30天后请求新内容 但是, ExpiresByType text/html "modification plus 2 hours" 没有直观的意义 除非浏览器缓存向服务器发出请求,否则它如何知道文件已被修改?如果它正在调用服务器,缓存这个指令有什么用?

在Apache的
mod_expires
模块中,有
expires
指令,有两个基本时间段,accessmodification

ExpiresByType text/html "access plus 30 days"
可以理解,这意味着缓存将在30天后请求新内容

但是,

ExpiresByType text/html "modification plus 2 hours"
没有直观的意义


除非浏览器缓存向服务器发出请求,否则它如何知道文件已被修改?如果它正在调用服务器,缓存这个指令有什么用?在我看来,我不理解缓存的某些关键部分。请告诉我。

我的理解是,修改要求浏览器根据上次修改的HTTP头的值确定缓存时间。因此,修改加上2小时将是最后一次修改的时间加上2小时。

服务器发送一个标题,例如:“
上次修改:Wed,2009年2月18日00:00:00 GMT
”。缓存的行为基于此标头或访问时间

比如说,如果内容预计每天刷新,那么您希望它在“修改加24小时”后过期


如果您不知道何时刷新内容,那么最好以访问时间为基础。

一个
Expires*
指令,以“modify”为基础表示服务器上文件的修改时间。因此,如果设置“修改加2小时”,则在文件修改后2小时内请求内容的任何浏览器(在服务器上)都会将该内容缓存到文件修改后2小时。并且浏览器知道该时间是什么时候,因为服务器发送了一个带有正确过期时间的
Expires

让我用一个例子来解释:假设您的Apache配置包括以下行

ExpiresDefault modification plus 2 hours
服务器上有一个文件
index.html
ExpiresDefault
指令适用于该文件。假设您在格林威治标准时间9:53上传了一个版本的
index.html
,覆盖了以前存在的
index.html
(如果有)。所以现在
index.html
的修改时间是格林威治标准时间9:53。如果您在服务器上运行
ls-l
(或在Windows上运行
dir
),您将在列表中看到它:

-rw-r--r--  1 apache apache    4096  Feb 18 09:53 index.html
现在,对于每个请求,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
如果浏览器发出此请求的时间在格林威治标准时间11:53之前,浏览器将缓存该页面,因为该页面尚未过期。因此,如果用户在格林威治时间11:00首先访问该页面,然后在格林威治时间11:30再次访问同一页面,浏览器将看到其缓存版本仍然有效,并且不会(或者更确切地说,不允许)发出新的HTTP请求

如果用户在格林威治标准时间12:00第三次访问该页面,浏览器会看到其缓存版本现在已过期(11:53之后),因此它会尝试验证该页面,并向服务器发送带有If-Modified-Since标头的请求。将返回304(未修改)无正文的响应,因为页面的日期自首次送达后未更改。由于过期日期已过——页面已“过时”——因此每次后续访问页面时都会发出验证请求,直到验证失败

现在,让我们假装你在11:57上传了新版本的页面。在这种情况下,浏览器尝试在12:00验证页面的旧版本失败,并在响应中与新页面一起接收以下两个新标题:

Last-Modified: Wed, 18 Feb 2009 11:57:00 GMT
Expires: Wed, 18 Feb 2009 13:57:00 GMT
(上传新版本后,文件的最后修改时间变为11:57,Apache将过期时间计算为11:57+2:00=13:57 GMT。)

现在直到13:57才需要验证(使用较新的日期)


(当然要注意,我上面列出的两个标题还附带了许多其他内容,为了简单起见,我只是删掉了其余部分)

首先,感谢David Z对上述内容的详细解释。在回答bushman关于在仍然需要服务器发出请求的情况下调用缓存为什么有意义的问题时,答案是服务器返回的内容节省了时间。如果cache指令指示文件的内容仍然是新的,则返回的不是返回的内容,而是带有空响应正文的304代码。这就是节省时间的地方

比我给出的更好的解释如下:

尽管条件请求确实会通过网络调用调用,但未修改的资源会导致响应正文为空,从而节省了将资源传输回最终客户端的成本。后端服务通常还能够非常快速地确定资源的最后修改日期,而无需访问资源,这本身就节省了大量的处理时间

基于时间的

基于时间的有条件请求确保仅当请求的资源在缓存浏览器副本后发生更改时,才会传输内容。如果缓存的副本是最新的,则服务器返回304响应代码

为了启用条件请求,应用程序通过last modified response标头指定资源的上次修改时间

缓存控制:公共,最大年龄=31536000 最后修改:2011年1月3日星期一格林威治标准时间17:45:57

下一次浏览器请求此资源时,仅当资源的内容自该日期起未更改时,才会使用if Modified-since请求标头请求该资源的内容

如果修改自:2011年1月3日星期一17:45:57 GMT

如果资源自2011年1月3日星期一格林威治时间17:45:57后未更改,服务器将返回一个带有30的空正文