浏览器不遵守HTTP Expires头部字段?

22

我的(嵌入式)Web服务器发送了Expires头,但浏览器似乎不遵守此头的设置,即如果我刷新页面,浏览器会请求应该被缓存的资源。以下是交换的标头:

https://192.168.1.180/scgi-bin/ajax/ajax.cgi
GET /scgi-bin/ajax/ajax.cgi HTTP/1.1 Host: 192.168.1.180 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Cache-Control: max-age=0
HTTP/1.x 200 OK Date: Wed, 24 Jun 2009 20:26:47 GMT Server: 嵌入式HTTP服务器。 Connection: close Content-Type: text/html ---------------------------------------------------------- https://192.168.1.180/scgi-bin/ajax/static.cgi?fn=images/logo.jpg&ts=20090624201057
GET /scgi-bin/ajax/static.cgi?fn=images/logo.jpg&ts=20090624201057 HTTP/1.1 Host: 192.168.1.180 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.11) Gecko/2009060215 Firefox/3.0.11 (.NET CLR 3.5.30729) Accept: image/png,image/*;q=0.8,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300连接:保持活动状态 引用者:https://192.168.1.180/scgi-bin/ajax/ajax.cgi 缓存控制:max-age=0
HTTP/1.x 200 OK 日期:2009年6月24日 星期三 20:26:47 GMT 服务器:嵌入式HTTP服务器。 连接:关闭 过期时间:2011年6月1日 星期三 20:00:00 GMT 内容类型:image/jpg ----------------------------------------------------------

ajax.cgi返回一个带有标志图形的HTML页面(通过static.cgi脚本),我希望缓存,但浏览器每次刷新都要求获取标志图形。


我看到你正在使用HTTPS工作。这可能是没有按照你的期望进行缓存的原因吗?你能否尝试使用仅HTTP版本? - mark
4个回答

18

如果您刷新页面,浏览器将忽略Expires头。它总是通过与Web服务器联系来检查缓存条目是否仍然有效。理想情况下,它会使用If-Modified-Since请求头,以便服务器可以返回“304 Not modified”如果缓存条目仍然有效。

由于您未设置Last-Modified头,因此浏览器必须执行无条件的GET以确保内容是最新的。

有关设置Expires和Last-Modified的一些经验法则在此博客文章中描述:

http://blog.httpwatch.com/2007/12/10/two-simple-rules-for-http-caching/


6
如果您刷新页面,浏览器会忽略“Expires”标头。谢谢!我之前并不知道这一点。 - Noah Sussman

14

你在浏览器里做了什么?看起来你点击了刷新按钮,甚至使用了类似 shift+Reload 的操作。通常情况下,浏览器不会发送 Cache-Control: max-age=0 标头。这意味着浏览器已经丢弃了缓存的图片并希望重新获取。

如果你只是导航到另一个页面,然后再回来,浏览器应该会遵循你的 Expires 标头。

此外,你可以在响应中添加一个 Cache-control: public 标头。这允许代理和浏览器显式地缓存图片。


1
这个看起来没错。浏览器(Firefox?)发送的是max-age=0,这意味着它不想要任何早于0秒的响应,即,它想要访问源网络服务器。这就是“刷新”的定义。离开你的页面,然后再次粘贴URL并观察会发生什么。 - Jim Ferrans
实际上,我执行了页面重载操作,本以为浏览器只会重新加载 HTML,但同时也重新加载了所有缓存的资源。我原本认为需要按 shift 键+单击(或按 control 键+单击?我记不清了)才能强制浏览器使所有资源的缓存失效。难道我的理解是错误的吗? - user128602
我也不确定。我认为在按下F5 /重新加载按钮时,带/不带Shift键,浏览器的行为是不同的。 - chris166
1
@user128602,刷新会忽略任何到期时间,但是在刷新时仍有机会利用浏览器缓存功能,这需要确保您的服务器发送文件的修改时间。通常情况下,除非您从脚本生成内容(如图像),否则服务器会发送修改时间以便浏览器进行下载。如果服务器发送了修改时间,则浏览器发出的下一个请求(包括重新加载)将向服务器发送“if-modified”。如果服务器响应为“not-modified”,则不执行下载操作。CTRL + 刷新意味着除了放弃缓存之外还要省略“if-modified”检查。 - doc_id

1

0
CGI脚本似乎有一个时间戳参数...这不会改变,对吧?浏览器应该将每个唯一的URL视为缓存中的不同对象,因此如果每个请求都更新,它将无法与缓存的图像匹配。
另外,Expires字段不完全符合RFC 1123格式,因为日期需要两位数字。这可能是问题,也可能不是问题,但需要检查一下。浏览器包括Cache-Control: max-age=0,这表示它认为其缓存可能已过期。
一旦服务器收到此验证请求,它可以返回304(未修改)200(OK),就像它目前正在做的那样。

不,时间戳没有改变。感谢您提供关于过期日期格式的提示,我会再次确认。 - user128602

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接