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

问题描述 投票:33回答:6

背景:

  • IIS 7
  • AspNet 3.5网络应用程序

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

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

Cache-Control: max-age=21600

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

iis google-chrome cache-control content-expiration
6个回答
68
投票

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

测试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>

另一种选择是复制URL并将其粘贴到同一选项卡或其他选项卡中。

更新:在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标头的形式实现此指令。

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


14
投票

如果您在同一个标​​签页中重新加载,Chrome似乎会忽略您的Cache-Control设置。如果您将URL复制到新选项卡并将其加载到那里,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

但是,访问相同的URL,来自多个新选项卡的http://localhost:4567/将从缓存中回收先前的结果。


13
投票

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

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

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

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


11
投票

如果Chrome开发者工具处于打开状态(F12),则Chrome通常会禁用缓存。

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


0
投票

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

这个错误报告中提到了这一点:https://bugs.chromium.org/p/chromium/issues/detail?id=110649


-2
投票

另一个提示:

不要忘记验证“日期”标题 - 如果服务器的日期/时间不正确(或位于另一个时区) - Chrome将一次又一次地请求资源。

© www.soinside.com 2019 - 2024. All rights reserved.