13.2.2启发式过期
由于源服务器并不总是提供明确的到期时间,因此HTTP缓存通常会分配启发式到期时间,使用使用其他标头值(例如Last-Modified时间)的算法来估计合理的到期时间。 HTTP / 1.1规范没有提供特定的算法,但确实对其结果施加了最坏情况的约束。由于启发式到期时间可能会影响语义透明度,因此应谨慎使用,我们鼓励源服务器尽可能提供明确的到期时间。 HTTP/1.1 RFC 2616
浏览器使用什么算法来估算合理的到期时间?
理想的答案将涵盖所有主要浏览器,并附有源代码或官方博客文章的证据。
答案 0 :(得分:10)
让我们假设我们感兴趣的所有浏览器都是Internet Explorer 8或更新版本(例如IE5在缓存标头方面有一些可怕的行为)。
只有一种基于标准的控制缓存方式(使用HTTP / 1.1引入) - Cache-Control
HTTP header。
由于至少1996年IE一直在使用退出策略来缓存HTTPS内容。
自从它推出以来,Chrome已经完成了对HTTPS的选择退出(即除非被告知否则会对其进行缓存)。 2011年,Firefox 4(但不是Safari)切换到HTTPS内容的选择退出缓存。 Source
仅使用HTTP标头来控制浏览器缓存。如果您决定反对这一点,请注意IE只识别在HTML中设置的两个缓存控制指令:
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1">
并且看起来只有前者在HTTPS场景中很有用。此外,可以problems when trying to use Pragma
in IE。最后,Chrome ignores cache directives in meta tags进一步降低了它们的实用性。
请勿使用Expires
标题。在现代浏览器中,Expires
被Cache-Control
取代。 Expires: 0
和Pragma: no-cache
技术上无效的响应标头。是的,它们从一开始就存在,但并非所有现代浏览器(例如Chrome)都使用它们,并且它们已被Cache-Control
取代。
Vary
标题是雷区。 How Vary
behaves in older IEs。 How Vary
behaves with XHR。查找详细信息是留给读者的练习 - 留下的印象是,最好对不同的内容使用不同的URL ...
允许浏览器通过设置ETags
来发出条件请求。
Etags allow a browser to do a lightweight check to see if the content has changed如果没有完整请求,则可以避免提出完整请求。
请注意,某些浏览器只是破解而且需要黑客。 IE 8 can have issues downloading files which it has been told not to cache
HttpResponseHeaders::GetFreshnessLifetimes()
nsHttpResponseHead::ComputeFreshnessLifetime()
。computeFreshnessLifetimeForHTTPFamily()
答案 1 :(得分:8)
此博客文章称,Internet Explorer 9使用max-age = (DownloadTime - LastModified) * 0.1
:http://blogs.msdn.com/b/ie/archive/2010/07/14/caching-improvements-in-internet-explorer-9.aspx
这与Mozilla有效(这篇文章相当陈旧,我不知道自那以后是否有所改变):https://developer.mozilla.org/en-US/docs/HTTP_Caching_FAQ
答案 2 :(得分:8)
来自Chromium的源代码:https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_response_headers.cc&l=1082&rcl=1421094684
if ((response_code_ == 200 || response_code_ == 203 ||
response_code_ == 206) && !must_revalidate) {
// TODO(darin): Implement a smarter heuristic.
Time last_modified_value;
if (GetLastModifiedValue(&last_modified_value)) {
// The last-modified value can be a date in the future!
if (last_modified_value <= date_value) {
lifetimes.freshness = (date_value - last_modified_value) / 10;
return lifetimes;
}
}
}
答案 3 :(得分:5)
似乎像webkit(&#34; ... Safari使用的引擎的OS X系统框架版本......&#34; )使用与Chromium相同的启发式方法。
以下摘自CacheValidation.cpp:
return (creationTime - lastModifiedValue) * 0.1;
答案 4 :(得分:3)
Gecko估计now + (now - lastModified)/10
到期,最后一次检查。