当前这些是正在发送/接收的标头;
第一个请求
客户端发送;
GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
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
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache
服务器响应;
HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000
因此,它将发送设置为365天的
HEAD
和Cache-Control
标头。不幸的是,在第二次刷新时,它再次使用Expires
标头再次请求对象。第二个请求
GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
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
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0
响应;
HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000
不幸的是,由于愚蠢的过时的代理软件,我们不能使用
If-Modified-Since
,也不能将任何其他服务器/代理放在应用程序的前面。我们也无法提高服务器性能并减少网络延迟。我一直在尝试找出可以发送哪些标头以摆脱301请求。我试过使用ETags,但这没什么区别,它仍然发送一个Keep-Alive
标头。我还尝试过删除If-modified-since
标头,但这只会导致不进行缓存的标准GET请求(检查日志,服务器仍在接收请求)。客户端混合使用Firefox(主要是IE) 7、8和(某些)9,Chrome和Safari,但此行为似乎已在所有经过测试的浏览器中出现。我发送通知客户,永远不要向服务器发送
Last-Modified
请求以验证其缓存,并保持内容缓存直到满足If-modified-since
标头为止?似乎产生相同的结果。我们的应用程序服务器前面有一个NGINX服务器,因此我可以随意添加/删除任何标头。我们的代理不支持Keep-Alive,也无法提高网络性能。由于糟糕的软件设计,Web应用程序在每个页面加载时加载+100资源(是的,企业软件很糟糕),每个对象的延迟约为40-50ms。
#1 楼
您无法真正控制用户代理决定发送给您的标头。如果有问题的文件在浏览器的缓存中,并且确定需要检查新版本,则它将进行检查。根据本文的介绍,以下是浏览器将使用If-Modified-Since进行请求的情况:第一次在浏览器会话中缓存的条目具有到期日期,但已过期
用户已通过单击“刷新”按钮或按F5来请求页面更新
因此,如果您正在重新加载页面以测试您的缓存,则它将无法正常工作,因为浏览器将重新请求图像。尝试单击一个链接,然后单击另一个链接返回首页。如果您的用户定期重新加载页面,则可能需要重新考虑您的站点/应用程序结构,以防止这种情况。最近我还了解到,超过一年的有效期无效。由于您的有效期限恰好是一年,因此,将其缩短几天或几周,可以确保文件保留在浏览器缓存中并且不会被丢弃。
评论
有趣的是,我将到期时间降低到60天,并添加公共标志,然后看看会发生什么。这似乎是在链接单击而不是F5上发生的(根据Firebug和服务器日志)
–涂抹
2012年2月1日于17:52
从技术上讲,HTTP / 1.1规范仅表示“服务器不应在未来一年内发送Expires日期”(大概是因为这要在到期前花费很长的时间),而将来的“大约一年”才是适当的到期时间需要发送永不过期的内容的时间。
–伊尔马里·卡洛宁(Ilmari Karonen)
2012年2月1日于19:07
经过一番摸索后,我得出结论说365d的有效期不会影响我们的客户,但是为了安全起见,我已将其丢弃,看来Cache-Control:public,...是此特定情况的关键。
–涂抹
2012年2月2日在8:42
您是说“公共”标头修复了不必要的往返吗?我尝试过,但是没有成功...
–phtrivier
13年1月16日在10:47
如果我的答案不清楚,则在浏览器中重新加载页面将再次请求文件。只需单击链接即可打开页面,浏览器将使用其缓存。
–心怀不满的山羊
13-10-18在12:37
#2 楼
您想要的是immutable
行中的Cache-Control
关键字。php的示例:
header('Cache-Control: public, max-age=80000, immutable');
源:
https://code.facebook .com / posts / 557147474482256 / this-browser-tweak-saved-60-requests-to-facebook /
#3 楼
我遇到了同样的问题,并且请求肯定会到达服务器以使其响应304
状态-我正在通过某些C#发送304,并确保它已到达服务器。仅设置了Cache-Control: private
。 No max-age
和no Expires
正常运行。用If-Modified-Since
击中服务器,在该服务器上测试与我期望值相比的值,并提供带空响应正文的304
-否则200
并填满响应正文。在客户端上,没有HTTP请求到达服务器。 但是..我发现同时设置
Expires
和200 - (from cache)
会导致浏览器不发送max-age=
标头,并且如果值不匹配则根本不缓存。 需要注意的是是否存在缓存问题,并且组合使用了不同的标头。
#4 楼
有点偏离主题,但可能会有所帮助。对缓存内容请求的另一项改进是在sessionStorage中进行缓存,这样您就无需让服务器验证缓存并接收304。例如google,打开控制台并编写sessionStorage。您将看到它们正在使用sessionStorage缓存CSS或DOM。 ofc,您不能在旧的IE浏览器中使用它。
#5 楼
查看您的源代码,并确保没有META REFRESH可以过渡到另一页。请改用sendRedirect之类的东西。在我的设置中,META REFRESH在IE中生成304,但在Chrome中不生成。 sendRedirect不会在任何一个浏览器上产生。<meta http-equiv="refresh" content="0;URL='nextpage'" />
vs
<% response.sendRedirect("nextpage") %>
#6 楼
我实际上正在寻找与此类似的答案。我的场景是我正在使用Apache httpd反向代理后端服务。我们想在代理服务器上引入
shared disk caching
。问题是页面已刷新或浏览器缓存正在针对服务器进行重新验证,这完全忽略了我们存储在服务器上的缓存(即使已缓存)。我们发现浏览器已明确传递了
max-age=0
如果是“ f5”或“ enter”,则为cache-control no-cache
,如果是ctrl+f5
,则此值已由代理服务器转发到下游。我们使用CacheIgnoreCacheControl to on
停止了此行为
评论
嗯,很奇怪。发送Expires和max age标头应防止进一步请求该图像。编辑:顺便问一下,将JPG作为文本/纯文本发送有什么处理?@DisgruntledGoat Ahh,您已经假设.jpg文件实际上是图像而不是文本文档。欢迎来到我的世界=)(实际上是一个文本文件,其中包含用于测试的“ Hello World”,该软件会按顺序将所有文件重命名为IMG_xxxx.jpg,无论类型如何。很酷吧?)
您用来设置http请求标头的是什么?