阅读了这里的许多文章和一些问题后,我终于成功激活了 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)。 这就是让我恼火的!
如果您有兴趣,我还附上了下面的图表:
编辑:现在刚刚也使用 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 附带的其他可用客户端解决方案,就会发现存在阻止资源加载的范围
- Cache Manifest (尽管有陷阱)
- IndexedDB (很好的异步功能,允许 blob 存储)
- Local Storage (非异步)
关于caching - 停止浏览器对应保留缓存的图像发出 HTTP 请求 - mod_expires,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10048740/