浏览器缓存控制、动态内容
问题:我似乎无法让 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 标头导致了问题?
Problem: I can't seem to get FireFox to cache images sent from a dynamic server
Setup: Static Apache Server with reverse proxy to a dynamic server (mod_perl2) at backend.
Here is the request URL for the server. It is sent to the the dynamic server, where the cookie is used to validate access to the image:
Request Headers
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
The dynamic server streams the image back to the server, and provides the following response:
Response Headers
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
So far, so good (me thinks). However, on reload of the page, the image does not appear cached, and a request is again sent:
Request Headers
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
It doesn't seem that request should happen as the browser should have cached the image. As it is, a 200 response is received, same as the first, and the image appears to be re-fetched (although the browser does appear to be using the cached images).
The problem appears to be hinted at by the Cache-Control: max-age=0 in the reload request header, above.
Does anyone know why this is happening? Perhaps it is the Via header in the response that is causing the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
原始请求
告诉所有中间 HTTP 缓存(包括 Firefox 的)您不想使用缓存的响应,您希望从原始 Web 服务器本身获取响应。
响应说:
这告诉大家,就源服务器而言,响应可能被缓存。服务器似乎配置为启用 PNG 图像缓存: HTTP 1.1< /a>(第 14.21 节)说:
您的第二个请求表示:
它告诉所有中间 HTTP 缓存您不会获取任何早于 0 秒的缓存响应。
需要注意的一件事是:如果您点击 Firefox 中的“重新加载”按钮,则表示您要求从源 Web 服务器重新加载。要测试图像的缓存,请离开页面然后返回,或在新选项卡中打开它。不知道为什么你第一次看到 no-cache 而第二次看到 max-age=0 。
顺便说一句,我喜欢 Firefox 的 FireBug 插件。您可以用它来查看请求和响应标头以及各种其他好东西。
The original request has
which tells all the intermediate HTTP caches (including Firefox's) that you don't want to use a cached response, you want to get the response from the origin web server itself.
The response says:
which tells everyone that as far as the origin server is concerned, the response may be cached. The server seems to be configured to enable the PNG image to be cached: HTTP 1.1 (section 14.21) says:
Your second request says:
which tells all the intermediate HTTP caches that you won't take any cached response older than 0 seconds.
One thing to watch out for: if you hit the Reload button in Firefox, you are asking to reload from the origin web server. To test the caching of the image, navigate away from the page and back, or open it up in a new tab. Not sure why you saw no-cache the first time and max-age=0 the second though.
BTW, I like the FireBug plug-in for Firefox. You can take a look at the request and response headers with it and all sorts of other good stuff.
我之前的回答仅部分正确。
问题是 FireFox 3 处理重新加载事件的方式。显然,它几乎总是再次从源服务器请求内容。因此
Cache-Control: max-age=0
请求标头。Firefox 确实使用缓存的图像在重新加载时呈现页面,但它仍然会“在后台”发出所有更新它们的请求。然后,它会在它们进入时替换它们。
因此,页面渲染速度很快,YSlow 报告缓存的内容。但服务器仍然被钉住。
解决方案是询问动态服务器脚本中的传入标头并确定是否提供了“If-Modified-Since”标头。如果是这种情况,并且确定内容未更改,则返回 HTTP_NOT_MODIFIED (304) 响应。
这不是最佳选择——我宁愿 Firefox 根本不发出请求——但它会将页面加载时间减少一半,并大大减少带宽。考虑到 Firefox 重新加载的工作方式,这似乎是最好的解决方案。
其他评论:Jim Ferran 关于离开页面并返回的观点有其优点 - 始终使用缓存,并且没有传出请求(+1 给 Jim)。此外,动态添加的内容(例如初始加载后的 AJAX 调用)似乎也使用缓存。
希望这对我以外的人有帮助:)
My previous answer was only partially correct.
The problem is the way FireFox 3 handles reload events. Apparently, it almost always requests content again from the origin server. Thus the
Cache-Control: max-age=0
request header.Firefox does use cached images to render a page on reload, but then it still makes all the requests to update them "in the background". It then replace them as they come in.
Therefore, the page renders fast, YSlow reports cached content. But the server is still getting nailed.
The resolution is to interrogate the incoming headers in the dynamic server script and determine if a 'If-Modified-Since' header is provided. If this is the case, and it is determined the content has not changed, an HTTP_NOT_MODIFIED (304) response is returned.
This is not optimal -- I'd rather Firefox not make the requests at all -- but it cuts the page load time in half, and greatly reduces bandwidth. Given the way Firefox works on reload, this appears the best solution.
Other Comments: Jim Ferran's point about navigating away from page and returning has merit -- the cache is always used, and no requests are outgoing (+1 to Jim). Also, content that is dynamically added (e.g. AJAX calls after the initial load) appear to use the cache as well.
Hope this helps someone besides me :)
看起来已经解决了:
Firebug 仍然显示来自源服务器的 200 个响应,但是,YSlow 将图像识别为缓存。根据YSlow的数据,新鲜时的总图片下载大小大于500K;缓存已启动后,它显示 0K 下载大小。
以下是来自 Origin 服务器的响应标头,它可以实现这一点:
由于我请求图像的方式,这些日期是否静态并不重要;我的应用程序知道请求图像之前的最后修改时间,并将其附加到客户端的请求 URL 中,为每个图像版本创建唯一的 URL,例如 http://myserver.com/img/125.jpg?20091122(该信息来自 AJAX JSON 提要)。例如,我可以将最后修改日期设置为 2000 年 1 月 1 日,并将过期日期设置为 2050 年的某个时间。
如果 YSlow 是正确的(并且性能测试表明它是正确的),那么 FireBug 应该真正报告这些本地缓存命中而不是200 回复。
Looks like solved it:
Firebug still shows 200 responses from the origin server, however, YSlow recognizes the images as cached. According to YSlow, total image download size when fresh is greater than 500K; with the cache primed, it shows 0K download size.
Here is the response header from the Origin server which does the trick:
Because of the way I'm requesting the images, it really should not matter if these dates are static; my app knows the last mod time before requesting the image and appends this to the request URL on the client side to create a unique URL for each image version, e.g. http://myserver.com/img/125.jpg?20091122 (the info comes from a AJAX JSON feed). I could, for example, make the last modified date 01 Jan 2000, and the Expires date sometime in the year 2050.
If YSlow is correct -- and performance testing implies it is -- then FireBug should really report these local cache hits instead of a 200 response.