caching - 停止浏览器对应保留缓存的图像发出 HTTP 请求 - mod_expires

标签 caching browser http-headers mod-expires

阅读了这里的许多文章和一些问题后,我终于成功激活了 Apache mod_expires 来告诉浏览器它必须将图像缓存 1 年

<filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</filesMatch>

值得庆幸的是,服务器响应似乎是正确的:

HTTP/1.1 200 OK 
Date: Fri, 06 Apr 2012 19:25:30 GMT 
Server: Apache 
Last-Modified: Tue, 26 Jul 2011 18:50:14 GMT 
Accept-Ranges: bytes 
Content-Length: 24884 
Cache-Control: max-age=31536000, public 
Expires: Sat, 06 Apr 2013 19:25:30 GMT
Connection: close
Content-Type: image/jpeg 

嗯,我认为这会阻止浏览器下载,甚至会在一年内停止向服务器查询图像。但这部分是正确的:因为如果您关闭并重新打开浏览器,浏览器不再从服务器下载图像但浏览器仍然通过每个图像的 HTTP 请求来查询服务器强>.

如何强制浏览器停止对每个图像发出 HTTP 请求?即使这些 HTTP 请求后面没有下载图像,它们仍然是向服务器发出的请求,这会不必要地增加延迟并减慢页面渲染速度!

我已经告诉浏览器它必须将图像在缓存中保留一年!为什么浏览器仍然向服务器查询每个图像(即使它不下载图像)?!

<小时/>

查看 FireBug 中的网络图(菜单 FireBug > 网络 > 图像),我可以看到不同的缓存行为(显然,我从浏览器缓存完全清空开始,我使用“清除所有历史记录”强制删除浏览器上的缓存):

  • 第一次加载页面时,所有图像都会下载(如果我通过单击浏览器的重新加载页面按钮强制页面重新加载,也会发生同样的情况)。 这是有道理的!

  • 当我浏览网站并返回同一页面时,根本不会下载图像,浏览器甚至不会向服务器询问任何图像的图像。 这是有道理的,(我希望在浏览器关闭时也能看到这种行为)!

  • 当我关闭浏览器并在同一页面上再次打开它时,愚蠢的浏览器无论如何都会为每个图像向服务器发出一次 HTTP 请求:它不会下载图像,但它仍然会发出一个HTTP请求,就像浏览器向服务器询问图像(服务器回复200 OK)。 这就是让我恼火的!

如果您有兴趣,我还附上了下面的图表:

enter image description here

enter image description here

编辑:现在刚刚也使用 FireFox 11.0 进行了测试,只是为了确保这不是我的 FireFox 3.6 太旧的问题。同样的事情发生!!! 我还测试了 Google 网站和 Stackoverflow 网站,它们都发送 Cache-Control: max-age=...浏览器仍然发出 HTTP 请求一旦浏览器关闭并在同一页面上再次打开,服务器响应后浏览器不会下载图像(正如我上面所解释的),但它仍然发出该死的请求,这会增加下载时间请参阅页面。

EDIT2:并按照建议删除 Last-Modified header here ,并不能解决问题,没有任何区别。

最佳答案

您看到的行为是预期的(有关更多详细信息,请参阅 RFC7234),指定的行为:

所有现代浏览器都会针对显示的每个页面元素向服务器发送 HTTP 请求,无论缓存状态如何。这是应 Web 服务(尤其是广告网络)的请求而做出的设计决策,以确保 HTTP 服务器能够维护每个元素的每次显示的记录。

如果浏览器没有发出这些请求,服务器将永远不会收到图像已向用户显示的通知。对于广告网络来说,这将是灾难性的。早期,广告网络通过使用随机生成的名称(例如:“coke_ad_1_98719283719283.gif”)提供相同的广告图像来解决这个问题。然而,对于 ISP 来说,这种做法导致数据传输量大幅增加,因为他们的每个用户都在重新下载这些相同的广告图像,绕过了 ISP 运行的任何缓存/代理服务器。

因此达成了休战协议(protocol):浏览器始终会发送 HTTP 请求,即使对于未过期的缓存元素也是如此。服务器将使用 HTTP 304 状态代码(“未修改”)进行响应。这允许服务器记录图像已显示给客户端的事实。因此,广告网络通常停止使用随机图像名称来绕过网络缓存服务器。

这为广告网络提供了他们想要的东西 - 显示的每个图像的记录 - 并且它为 ISP 提供了他们想要的东西 - 可缓存的图像和静态内容。

这就是为什么您无法阻止浏览器发送对缓存页面元素的 HTTP 请求。

但是,如果您查看 html5 附带的其他可用客户端解决方案,就会发现存在阻止资源加载的范围

  1. Cache Manifest (尽管有陷阱)
  2. IndexedDB (很好的异步功能,允许 blob 存储)
  3. Local Storage (非异步)

关于caching - 停止浏览器对应保留缓存的图像发出 HTTP 请求 - mod_expires,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10048740/

相关文章:

javascript - 检测用户是否在域上启用了位置服务

c# - Web 浏览器多线程转换异常

amazon-s3 - S3 x-amz-meta- 区分大小写

caching - 客户端缓存资源多长时间?

visual-studio-2010 - _mm_prefetch 如何工作?

sql - WCF 服务 : ASP. NET 缓存或 SQL

java - Appengine 位置 header 在什么基础上告知位置?

ruby-on-rails - 带有嵌套对象的 Rabl 缓存

c# - 嵌入式 WebBrowser Web 控制台访问

ios - NSURLConnection 授权 header 不起作用