在这里阅读了很多文章和一些问题之后,我终于成功激活了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
好吧,我认为这会阻止浏览器下载甚至向服务器询问有关图像的信息,为期1年。但这部分是正确的:如果你关闭并重新打开浏览器会导致,浏览器不再从服务器下载图像,但浏览器仍然会向服务器询问每个图像的HTTP请求
如何强制浏览器停止为每个图像发出HTTP请求?即使这些HTTP请求后面没有下载的图像,它们仍然是向服务器发出的请求,这意味着不必要的延迟,并减慢页面渲染速度!
我已经告诉浏览器它必须将图像保存在缓存中1年!为什么浏览器仍在为每个图像查询服务器(即使它没有下载图像)?!
查看FireBug中的网络图(菜单FireBug&gt; Net&gt;图像)我可以看到不同的缓存行为(我显然开始使用浏览器缓存完全空,我使用“清除所有历史记录”强制在浏览器上删除缓存) :
当第一次加载页面时,所有图像都被下载(如果我通过单击浏览器的重新加载页面按钮强制页面重新加载,则会发生同样的事情)。 这是有道理的!
当我浏览网站并返回同一页面时,根本不会下载图片,浏览器甚至不会向服务器查询的图像。 这是有道理的(我希望在浏览器关闭时也能看到这种行为)!
当我关闭浏览器并在同一页面上再次打开它时,愚蠢的浏览器无论如何都会向每台图像的服务器发出一次HTTP请求:它不会使图像下载,但它仍会生成HTTP请求,就像浏览器向服务器查询图像(服务器回复200 OK)。 这是令我恼火的人!
如果您有兴趣,我也会附上以下图表:
编辑:刚刚使用FireFox 11.0进行测试,以确保它不是我的FireFox 3.6太老的问题。同样的事情发生了! 我还测试了Google网站和Stackoverflow网站,他们都发送了
Cache-Control: max-age=...
但浏览器关闭并打开后,浏览器仍会向服务器发出HTTP请求再次在同一页上,在服务器响应之后,浏览器不会下载图像(如上所述)但它仍然会发出该死的请求,这会增加查看页面的时间。
EDIT2:并按照建议的here移除Last-Modified
标题,但无法解决问题,它没有任何区别。
答案 0 :(得分:28)
您看到的行为是预期的(有关详细信息,请参阅RFC7234),指定的行为:
所有现代浏览器都会针对显示的每个页面元素向服务器发送HTTP请求,而不管缓存状态如何。这是根据Web服务(尤其是广告网络)的要求做出的设计决策,以确保HTTP服务器能够维护每个元素的每个显示的记录。
如果浏览器没有发出这些请求,则永远不会通知服务器已向用户显示图像。对于广告网络来说,这将是灾难性的。早期,广告网络通过使用随机生成的名称提供相同的广告图片来“破解”他们的方式(例如:'coke_ad_1_98719283719283.gif')。但是,对于互联网服务提供商而言,这种做法导致数据传输量大幅增加,因为他们的每个用户都在重新下载这些相同的广告图像,绕过他们的ISP正在运行的任何缓存/代理服务器。
因此达成了休战:浏览器总是会发送HTTP请求,即使对于未过期的缓存元素也是如此。服务器将使用HTTP 304状态代码(“未修改”)进行响应。这允许服务器记录图像显示给客户端的事实。因此,广告网络通常停止使用随机图像名称来绕过网络缓存服务器。
这为广告网络提供了他们想要的东西 - 显示每张图片的记录 - 它为ISP提供了他们想要的东西 - 可缓存的图像和静态内容。
这就是为什么你无法阻止浏览器发送缓存页面元素的HTTP请求。
但是如果你看一下html5附带的其他可用的客户端解决方案,还有一个阻止资源加载的范围
答案 1 :(得分:14)
您使用了错误的工具来分析请求。
我建议使用真正有用的Firefox插件 Live HTTP标头,这样您就可以看到网络上的实际情况。
而且可以肯定的是,你可以ssh / putty你的服务器并执行类似
的操作tail -f /var/log/apache2/access.log
答案 2 :(得分:12)
“重新加载”和“刷新”之间存在差异。导航到具有后退和前进按钮的页面通常不会发起新的HTTP请求,但是专门按F5“刷新”页面将导致浏览器仔细检查其缓存。这取决于浏览器,但似乎是FF和Chrome的标准(即能够轻松查看其网络流量的浏览器。)点击F6,输入应该关注URL地址栏然后“转到”它,这应该重新加载页面,但不要仔细检查页面上的资产。
更新:澄清后退和前进导航行为。它在浏览器中称为“后退缓存”或 BFCache 。当您使用后退/前进按钮导航时,意图是在您在自己的时间轴中看到页面时显示的页面。使用后退和前进时不会发出任何服务器请求,即使服务器缓存标头表明特定项目已过期。
如果你在开发者网络面板中看到(200 OK BFCache),那么服务器从未被命中 - 甚至要求if-modified-since。
http://www.softwareishard.com/blog/firebug/firebug-tip-what-the-heck-is-bfcache/
答案 3 :(得分:7)
如果我使用F5或F5 + Ctrl强制刷新,则发送请求。但是,如果我关闭浏览器并再次输入url,则会发送NO reqeust。我测试是否发送请求的方式是在服务器上的开始请求中使用断点,即使请求未发送,它仍然在Firebug中显示为已经完成7毫秒等待,所以要小心这一点。
答案 4 :(得分:6)
您在此描述的内容并不反映我的经验。如果内容是使用no-store指令提供的,或者你进行了明确的刷新,那么是的,我希望它能回到源服务器,否则它应该在浏览器重启时缓存(假设它被允许,并且可以写缓存文件)。
更详细地看一下您的瀑布(由于它们有点小而且模糊不清,这很棘手),浏览器似乎正在做它应该做的事情 - 它有条目的图像 - 但这些只是从本地缓存而不是从源服务器加载 - 检查响应中的'Date'标头(为什么你认为它需要几毫秒而不是几秒?)。这就是为什么它们的颜色不同。
答案 5 :(得分:4)
在我花了相当多的时间寻找合理的答案后,我发现以下链接最有用,它确实回答了这里提出的问题。
答案 6 :(得分:0)
如果是生死攸关的问题(如果你想以这种方式优化页面加载,或者如果你想尽可能减少服务器上的负载,那么就有一种解决方法。) p>
首次使用HTML5 本地存储缓存图片。
[+] 您可以阻止浏览器发送HTTP请求,无论用户多么努力(F5,ctrl + F5,99%)都会返回304(未修改)只是重新访问页面等。)
[ - ] 您必须在javascript支持方面加倍努力。
[ - ] 图像存储在base64中(我们无法存储二进制数据),这就是为什么每次在客户端解码它们的原因。哪个通常非常快,而且不是什么大问题,但它仍然是客户端的一些额外的CPU使用,应该牢记。
[ - ] 本地存储空间有限。您可以瞄准每个域使用~5mb的数据(注意:base64会增加~30%的原始图像大小)。
[?] 支持多数浏览器。 http://caniuse.com/#search=localstorage
答案 7 :(得分:0)
您在Chrome中看到的并不是实际HTTP请求的记录 - 它是资产请求的记录。 Chrome会执行此操作以向您显示页面实际上正在请求资产。但是,此视图实际上并不真正表明是否正在进行请求。如果资产已缓存,Chrome将永远不会实际创建基础HTTP请求。
您也可以将鼠标悬停在时间轴中的紫色片段上进行确认。缓存资源在工具提示中将有(from cache)
。
要查看实际的HTTP请求,您需要查看较低级别。在某些浏览器中,这可以通过插件(如Live HTTP Headers)来完成。
实际上,要验证请求实际上并未实现,您需要检查服务器日志或使用Charles或Fiddler之类的调试代理。这将在HTTP级别上工作,以确保请求实际上不会发生。
答案 8 :(得分:0)
缓存验证和304响应
在许多情况下,Internet Explorer需要检查缓存条目是否有效:
缓存条目没有到期日期,并且首次在浏览器会话中访问内容
缓存条目的截止日期已过期
如果缓存的条目具有最后修改日期,IE会在GET请求消息的If-Modified-Since标头中发送它:
GET /images/logo.gif HTTP/1.1
Accept: */*
Referer: http://www.google.com/
Accept-Encoding: gzip, deflate
If-Modified-Since: Thu, 23 Sep 2004 17:42:04 GMT
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;)
Host: www.google.com
服务器检查If-Modified-Since标头并做出相应的响应。如果自指定的日期/时间以来内容未更改,则它将回复状态代码304和仅包含标题的响应消息:
HTTP/1.1 304 Not Modified
Content-Type: text/html
Server: GWS/2.1
Content-Length: 0
Date: Thu, 04 Oct 2004 12:00:00 GMT
可以快速下载响应,因为它不包含任何内容并导致IE从缓存中读取所需的数据。实际上,它就像是重定向到本地浏览器缓存。
如果请求的对象自If-Modified-Since标头中的日期/时间以来实际发生了更改,则服务器响应状态代码为200并提供修改后的资源版本。
答案 9 :(得分:0)