浏览器什么时候刷新过时的缓存条目?

时间:2014-01-30 22:20:46

标签: http caching

我一直在尝试刷新我对HTTP / 1.1缓存的理解 - 我发现每隔一段时间我就必须做一些事情,因为似乎有太多可能的组合可以让我的大脑可靠地记住。

我认为Expiresmax-age缓存控制指令被浏览器用作提示,而非铁定律:如果缓存条目过时(早于其最大年龄),浏览器可以验证它。

一位同事和我有一点关于这一点,他强迫我阅读RFC,我觉得它有点苛刻,但证明他完全正确:如果我理解正确,客户不允许使用他们知道过时的缓存条目。

换句话说:如果文档指定max-age缓存标头,并且没有其他指令(如must-validate)影响缓存行为,并且该文档的缓存条目变得陈旧,则浏览器将始终重新验证它

这是完全清楚和合乎逻辑的,为了让这个论点得到休息,我开始通过让服务器提供带有以下标题的测试JavaScript文件来凭经验确认:

< HTTP/1.1 200 OK
< Content-Type: application/x-javascript; charset=UTF-8
< Cache-Control: public, max-age=30
< Date: Thu, 30 Jan 2014 22:11:28 GMT
< Accept-Ranges: bytes
< Server: testServer/1.0
< Vary: Accept-Encoding
< Transfer-Encoding: chunked

此JavaScript文件包含在同一服务器上通过文档<script>中的<head>元素托管的HTML页面中。 HTML页面提供以下缓存控制标头:

Cache-Control: no-cache, must-revalidate, no-store, max-age=0

加载HTML页面后,我点击进入另一个页面,等待5分钟以获得良好的衡量标准,然后点击返回原始页面的链接,监控所有HTTP请求 - 并且从未请求过测试文件。这是与Firefox和Safari最新版本一致的再现。

这有点啰嗦,但我的问题的主旨是:我的测试似乎表明主流浏览器不尊重RFC,也不会重新验证过时的缓存条目。我误解了RFC吗?同样可能的是,我是否对我的测试进行了测试,有人可以证明他们错了吗?或者浏览器真的不尊重max-age缓存指令吗?

2 个答案:

答案 0 :(得分:1)

经过@CodeCaster的大量挖掘和帮助后,这个问题的典型答案是浏览器看起来似乎尊重RFC:过时的缓存条目总是被重新验证,除非是在直接或直接访问它们的特定情况下间接地,通过浏览器的历史。在这种情况下,RFC的13.3部分适用:

  

历史机制和缓存是不同的。特别是历史机制不应该试图显示资源当前状态的语义透明视图。相反,历史机制旨在准确显示用户在检索资源时看到的内容。

答案 1 :(得分:0)

我无法重现您的问题。我尝试使用ASP.NET MVC,使用以下代码:

public ActionResult Index()
{
    Response.AddHeader("Cache-Control", 
                       "no-cache, must-revalidate, no-store, max-age=0");
    return View();
}

public ActionResult JavaScript()
{
    Response.AddHeader("Cache-Control", "public, max-age=30");
    return View();
}

public ActionResult Page2()
{
    return View();
}

第一个操作返回索引页面(仅限相关标题):

HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, must-revalidate, max-age=0
Pragma: no-cache
Expires: -1
Vary: Accept-Encoding
Content-Length: 182


<html>
    <head>
        <script src="/Home/JavaScript" type="text/javascript"></script>
    </head>
    <body>
        <a href="/Home/Page2">Page 2</a>
    </body>
</html>

JavaScript返回如下:

HTTP/1.1 200 OK
Cache-Control: public, max-age=30
Vary: Accept-Encoding
Content-Length: 24


document.write('Foo');

而Page2只包含一个返回Home的链接。

现在,当我使用Internet Explorer 11,Chrome 32或Firefox 26时,我看到以下行为:

  • 在第一次请求/时,请求索引文档以及JavaScript文件,并返回如上所示,并通过Fiddler验证。
  • 当我点击“第2页”链接时,只请求第2页,因为除了返回第1页的链接之外,它不包含任何内容。
  • 现在,当我在30秒内点击第2页的“主页”链接时,JS文件在任何浏览器中都会再次 >。
  • 当我在第2页上等待一段时间(> 30秒)然后点击“主页”链接时,在所有三个浏览器中都要求 的JS文件。

但是,当我在任何浏览器中在任何浏览器中单击“后退”按钮一段时间后(大于或小于30秒),索引文件始终是,但JS文件是从不在任何浏览器中再次请求。

需要刷新(F5)或通过再次单击“Page 2”然后再返回“Home”来导航和返回,以使浏览器在JS文件过期后执行新的请求。