浏览器缓存控制,动态内容

时间:2009-11-24 04:47:33

标签: browser mod-perl2 cache-control

问题:我似乎无法让FireFox缓存从动态服务器发送的图像

设置:静态Apache服务器,在后端具有反向代理到动态服务器(mod_perl2)。

以下是服务器的请求URL。它被发送到动态服务器,其中cookie用于验证对图像的访问:

请求标题

Host:  <OBSCURED>
User-Agent:  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
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
Connection:  keep-alive
Referer: <OBSCURED>
Cookie:  pz_cred=4KCNr0RM15%2FJCOt%2BEa6%2BL62z%2Fxvbp2xNQHY5pJw5d6Q
Pragma:  no-cache
Cache-Control: no-cache

动态服务器将图像流回服务器,并提供以下响应:

响应标题

Date:  Tue, 24 Nov 2009 04:28:07 GMT
Server:  Apache/2.2.11 (Ubuntu) mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
Cache-Control: public, max-age=31536000
Content-Length:  25496
Content-Type:  image/jpeg
Via: 1.1 127.0.1.1:8081
Keep-Alive:  timeout=15, max=75
Connection:  Keep-Alive

到目前为止,这么好(我想)。但是,重新加载页面时,图片不会显示为缓存,并且会再次发送请求:

请求标题

Host: <OBSCURED>
User-Agent:  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.15) Gecko/2009102815 Ubuntu/9.04 (jaunty) Firefox/3.0.15
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
Connection:  keep-alive
Referer: <OBSCURED>
Cookie:  pz_cred=4KCNr0RM15%2FJCOt%2BEa6%2BL62z%2Fxvbp2xNQHY5pJw5d6Q
Cache-Control: max-age=0

似乎请求不应该发生,因为浏览器应该缓存图像。实际上,接收到200响应,与第一个响应相同,并且图像似乎被重新获取(尽管浏览器似乎确实使用了缓存图像)。

上面的重新加载请求标头中的Cache-Control:max-age = 0似乎暗示了这个问题。

有谁知道为什么会这样?也许是导致问题的响应中的 Via 标题?

3 个答案:

答案 0 :(得分:5)

原始请求

Cache-Control: no-cache

告诉所有中间HTTP缓存(包括Firefox)您不想使用缓存响应,您希望从原始Web服务器本身获取响应。

回复说:

Cache-Control: public, max-age=31536000

告诉大家,就原始服务器而言,响应可能被缓存。服务器似乎配置为允许缓存PNG图像:HTTP 1.1(第14.21节)说:

  

注意:如果回复包含a   具有max-age的Cache-Control字段   指令(见第14.9.3节),即   指令覆盖Expires字段。

你的第二个要求是:

Cache-Control: max-age=0

告诉所有中间HTTP缓存,您不会接受任何超过0秒的缓存响应。

需要注意的一件事是:如果您点击Firefox中的“重新加载”按钮,则要求从原始Web服务器重新加载。要测试图像的缓存,请离开页面并返回,或在新选项卡中打开它。不知道为什么你第一次看到no-cache而max-age = 0则是第二次。

BTW,我喜欢Firefox的FireBug插件。您可以查看请求和响应标头以及各种其他好东西。

答案 1 :(得分:3)

我之前的回答只是部分正确。

问题是FireFox 3处理重新加载事件的方式。显然,它几乎总是从源服务器再次请求内容。因此Cache-Control: max-age=0请求标头。

Firefox 确实使用缓存的图片在重新加载时呈现页面,但它仍然会“在后台”发出更新请求的所有请求。然后在它们进来时替换它们。

因此,页面渲染速度快,YSlow报告缓存内容。但是服务器仍然被钉死了。

解决方案是询问动态服务器脚本中的传入标头,并确定是否提供了“If-Modified-Since”标头。如果是这种情况,并且确定内容未更改,则返回HTTP_NOT_MODIFIED(304)响应。

这不是最佳的 - 我宁愿Firefox根本不提出请求 - 但它会将页面加载时间缩短一半,并大大减少带宽。鉴于Firefox在重新加载方面的工作方式,这似乎是最佳解决方案。

其他评论:Jim Ferran关于导航离开页面并返回的观点有其优点 - 始终使用缓存,并且没有任何请求传出(+1给吉姆)。此外,动态添加的内容(例如初始加载后的AJAX调用)似乎也使用缓存。

希望这可以帮助除了我以外的人:)

答案 2 :(得分:1)

看起来解决了它:

  • 通过标题
  • 删除了代理
  • 添加了Last-Modified标头
  • 添加了远期过期日期

Firebug仍然显示来自原始服务器的200个响应,但是,YSlow将图像识别为缓存。根据YSlow,新鲜时的总图像下载大小大于500K;启动缓存后,它显示0K下载大小。

这是来自Origin服务器的响应头,它可以解决这个问题:

Date: Tue, 24 Nov 2009 08:54:24 GMT
Server: Apache/2.2.11 (Ubuntu) mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0
Last-Modified: Sun, 22 Nov 2009 07:28:25 GMT
Expires: Tue, 30 Nov 2010 19:00:25 GMT
Content-Length: 10883
Content-Type: image/jpeg
Keep-Alive: timeout=15, max=89
Connection: Keep-Alive

由于我要求图像的方式,如果这些日期是静态的,那真的无关紧要;我的应用程序知道请求图像之前的最后一个模式时间,并将其附加到客户端的请求URL,以便为每个图像版本创建一个唯一的URL,例如, http://myserver.com/img/125.jpg?20091122(信息来自AJAX JSON提要)。例如,我可以在2000年1月1日进行最后修改日期,并在2050年的某个时间进行到期日期。

如果YSlow是正确的 - 并且性能测试暗示它是 - 那么FireBug应该真的报告这些本地缓存命中而不是200响应。