【问题标题】:Is Chrome ignoring Cache-Control: max-age?Chrome 是否忽略了 Cache-Control: max-age?
【发布时间】:2012-06-30 00:57:00
【问题描述】:

背景:

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

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

在 IIS 7 中,我为缓存控制设置了 HTTP 标头,将“资源”文件夹设置为 6 小时。在 Chrome 中,使用开发工具,我可以看到标题设置得很好:

Cache-Control: max-age=21600

但我仍然收到 98 个请求...我认为如果未达到过期日期,浏览器不应该请求一个资源,并且我希望请求数下降...

【问题讨论】:

  • 我遇到了类似的问题。 Chrome 似乎完全忽略了缓存标头。
  • 我使用 10 秒的 max-age 进行测试,而 nothing 曾经工作过,但是如果我做 30 秒,那么一切都会按预期工作。 Chrome 似乎有一个最短缓存时间,低于这个时间就会被忽略。

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


【解决方案1】:

我明白了。如果您在同一选项卡中对同一 URI 的另一个请求之后立即发出请求(通过单击刷新按钮、按 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>

另一种选择是复制 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 实施了我们的一位工程师提出的一项建议,即为某些资源添加一个新的缓存控制标头,以便告诉浏览器永远不应重新验证该资源。这个标头背后的想法是,它是开发人员向浏览器额外承诺的,即该资源在其 max-age 生命周期内永远不会改变。 Firefox 选择以 cache-control: immutable header 的形式来实现这个指令。

我希望这有助于解开重新加载的谜团。

【讨论】:

  • 这不就是缓存的目的吗?
  • 一个更简单的测试方法是将你的 URL 复制到一个新标签中:)
  • Chrome 只能在隐身模式下从缓存中加载,而在其他模式下则不会,这非常奇怪!
  • F5Ctrl-R 是一个要求浏览器重置缓存的重新加载命令......它不是特定于 Chrome。此外,如果服务器想要考虑到这一点,则会将 Cache-Control: no-cache 标头发送到服务器......(这对于可以缓存您的页面的代理很重要。)
  • @AlexisWilke F5 不应该清除缓存,在 Win/Linux 上您必须按 F5+Ctrl 刷新页面 + 清除缓存(参见:en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache
【解决方案2】:

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

可在开发者工具设置中进行控制 - 开发工具顶部栏右侧的齿轮图标。

【讨论】:

  • 我没有选中那个框,但它仍然没有正确缓存。该框显示:“禁用缓存(在 DevTools 打开时)”。
【解决方案3】:

如果您在同一标签中重新加载,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/ 会从缓存中回收之前的结果。

【讨论】:

  • 这正是我需要的答案。和 Chrome 打了一个小时,试图找出正确的 Cache headers 组合,终于找到了这个帖子和 bam,不用担心。
  • 发现了同样的东西。在地址栏中点击刷新或点击“回车”会导致 Chrome 忽略缓存。从新选项卡访问 URL 将使用缓存。
  • 我在缓存指令中使用元标记,chrome 仍然忽略它们,但 Microsoft edge 和 Microsoft edge beta 服从缓存。这个标题我已经有一段时间了
【解决方案4】:

Cache-Control:max-age=xxx做一些测试后:

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

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

注意:右键单击刷新图标将显示刷新选项(正常、硬、空缓存)。令人难以置信的是,这些都不会影响这些标头。

【讨论】:

  • 自 2018 年 6 月 6 日起,Chrome 不再支持“不可变”标志,您必须使用“max-age=xxx”或其朋友。
【解决方案5】:

另一个提示:

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

【讨论】:

  • 这毫无意义。当来自美国的人访问不同时区的网站时,缓存仍然有效。
  • 检查服务器时钟偏差很有意义。但是是的,首先验证所有时间都是UTC。时区应该不是问题。
【解决方案6】:

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

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

【讨论】:

  • 这让我发疯了......两次!谢谢!一旦我发现这是问题所在,我就简单地切换到 ngrok,它为您提供了一个有效的通配符 SSL 进行测试,然后我就开始做生意了。另外,另一个问题是,如果您在 Chrome DevTools 打开的情况下进行测试,请确保关闭“缓存(当 DevTools 处于打开状态时)”设置。
【解决方案7】:

这是对kievic answer的补充

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

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

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

【讨论】:

    【解决方案8】:

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

    “有时”,因为在我的例子中,缓存控制指令适用于小图像(~60-200KB),但不适用于较大的图像(10MB)。

    不使用隐身窗口导致 Chrome 使用磁盘缓存版本,即使是大图像。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-15
      • 2022-01-22
      • 2014-06-25
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多