问题:我似乎无法让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 标题?
答案 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)
看起来解决了它:
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响应。