Chrome是否忽略了Cache-Control:max-age?

时间:2012-06-28 13:29:51

标签: iis google-chrome cache-control content-expiration

背景:

  • IIS 7
  • AspNet 3.5网络应用

Chrome开发工具列出了对网络应用主页的98个请求(aspx + js + css +图像)。在以下请求中,css / images文件的状态代码为200。没有缓存信息,浏览器每次询问服务器是否必须更新文件。行。

在IIS 7中,我为缓存控制设置HTTP标头,为“ressources”文件夹设置为6小时。在Chrome中,使用开发工具,我可以看到标题设置正确:

Cache-Control: max-age=21600

但是我仍然收到98个请求......我认为如果没有达到过期日期,浏览器不应该请求一个ressource,而且我期待请求数量下降......

8 个答案:

答案 0 :(得分:66)

我明白了。如果您在同一标签中对同一URI的另一个请求后立即发出请求,则Google Chrome会忽略Cache-ControlExpires标头(通过点击刷新按钮,按 F5 键或按命令 + R )。它可能有一个算法来猜测用户真正想做什么。

测试Cache-Control标头的一种方法是返回带有自身链接的HTML文档。点击该链接后,Chrome会从缓存中提供文档。例如,将以下文档命名为 self.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Test Page</title>
</head>
<body>
    <p>
        <a href="self.html">Link to the same page.</a>
        If correctly cached, a request should not be made
        when clicking the link.
    </p>
</body>
</html>

另一种选择是复制网址并将其粘贴到同一标签或其他标签中。

更新:在Chrome post published on January 26, 2017上,通过仅重新验证主要资源来描述之前的行为及其变化方式,但不是子资源

  

用户通常会重新加载,因为页面已损坏或内容似乎过时。现有的重新加载行为通常可以解决损坏的页面,但是通过定期重新加载来解决过时的内容,尤其是在移动设备上。此功能最初是在破碎页面非常普遍的时候设计的,因此同时处理这两个用例是合理的。然而,随着网页质量的提高,这种原始问题现在变得不那么重要了。为了改善过时的内容使用案例,Chrome现在具有简化的重新加载行为,仅验证主要资源并继续常规页面加载。这种新行为可以最大限度地重用缓存资源,从而降低延迟,功耗和数据使用率。

Facebook post also published on January 26, 2017中,提到他们发现piece of code Chrome在POST请求后使所有缓存资源无效:

  

我们发现Chrome会重新验证从发出POST请求加载的网页上的所有资源。 Chrome团队告诉我们,理由是POST请求往往是进行更改的页面 - 比如购买或发送电子邮件 - 并且用户希望拥有最新的页面。

似乎情况不再如此。

最后,描述了Firefox正在引入Cache-Control: immutable以完全停止资源的重新验证:

  

Firefox实施了我们的一位工程师的建议,为某些资源添加新的缓存控制标头,以告诉浏览器永远不应该重新验证此资源。这个标题背后的想法是,它是开发人员对浏览器的额外承诺,即该资源在其最大使用期限内永远不会改变。 Firefox选择以cache-control:immutable header的形式实现该指令。

我希望这有助于解开重装神秘。

答案 1 :(得分:13)

如果您在同一个标​​签页中重新加载,Chrome似乎会忽略您的Cache-Control设置。如果您将该网址复制到新标签页并将其加载,则Chrome会尊重缓存控制标记并重新使用缓存中的内容。

作为一个例子,我有这个Ruby Sinatra应用程序:

#!/usr/bin/env ruby

require 'sinatra'

before do
  content_type :txt
end

get '/' do
  headers "Cache-Control" => "public, must-revalidate, max-age=3600",
          "Expires" => Time.at(Time.now.to_i + (60 * 60)).to_s
  "This page rendered at #{Time.now}."
end

当我在同一个Chrome标签页中连续重新加载它时,它会显示新的时间。

This page rendered at 2014-10-08 13:36:46 -0400.
This page rendered at 2014-10-08 13:36:48 -0400.

标题看起来像这样:

< HTTP/1.1 200 OK
< Content-Type: text/plain;charset=utf-8
< Cache-Control: public, must-revalidate, max-age=3600
< Expires: 2014-10-08 13:36:46 -0400
< Content-Length: 48
< X-Content-Type-Options: nosniff
< Connection: keep-alive
* Server thin is not blacklisted
< Server: thin

但是,访问同一个网址,来自多个新标签的http://localhost:4567/会从缓存中回收以前的结果。

答案 2 :(得分:13)

使用Cache-Control:max-age=xxx进行一些测试后:

  • 按重新加载按钮:标题忽略
  • 输入相同网址的任何标签(当前与否):荣幸
  • 使用JS(window.location.reload()):忽略
  • 使用开发者工具(未选中禁用缓存)或隐身不会影响

因此,开发时的最佳选择是将光标放在多功能框中并按Enter 而不是刷新按钮。

注意:右键单击刷新图标将显示刷新选项(正常,硬,空缓存)。令人难以置信的是,这些标题中没有一个会影响这些标题。

答案 3 :(得分:9)

如果Chrome开发者工具已打开(F12),Chrome通常会停用缓存。

它可以在开发人员工具设置中控制 - 开发工具顶部栏右侧的齿轮图标。

答案 4 :(得分:0)

虽然这个问题很旧,但我想补充一点,如果您正在通过https使用自签名证书进行开发,并且证书存在问题,那么无论您使用哪种缓存标头,google都不会缓存响应。 / p>

此错误报告中对此进行了说明: https://bugs.chromium.org/p/chromium/issues/detail?id=110649

答案 5 :(得分:0)

这是kievic answer

的附加内容

要强制浏览器不在请求中发送Cache-Control标头,请打开chrome控制台并输入:

location = "https://your.page.com"

要强制浏览器添加此标头,请点击“重新加载”按钮。

答案 6 :(得分:0)

还是一个老问题,但我最近才注意到(2020年),当使用隐身窗口浏览时,Chrome有时会忽略图像资源的Cache-Control标头。

“有时”是因为在我的情况下,Cache-Control指令仅适用于较小的图像(约60-200KB),而不适用于较大的图像(10MB)。

如果不使用隐身窗口,Chrome甚至会对大图像使用磁盘缓存版本。

答案 7 :(得分:-2)

另一个提示:

不要忘记验证&#34;日期&#34;标题 - 如果服务器的日期/时间不正确(或位于其他时区),Chrome将一次又一次地请求资源。