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

Fra*_*ois 38 iis google-chrome cache-control content-expiration

背景:

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

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

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

Cache-Control: max-age=21600
Run Code Online (Sandbox Code Playgroud)

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

kie*_*wic 72

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

测试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>
Run Code Online (Sandbox Code Playgroud)

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

更新:在2017年1月26日发布Chrome帖子上,通过仅重新验证主要资源而不是子资源来描述之前的行为及其变化情况:

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

2017年1月26日发布Facebook帖子中,提到他们发现一段代码是Chrome在POST请求后使所有缓存资源无效:

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

似乎情况不再如此.

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

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

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

  • 一种更简单的测试方法是将您的URL复制到新标签:) (6认同)
  • @AlexisWilke F5不应该清除缓存,在Win/Linux上你必须按F5 + Ctrl刷新页面+清除缓存(参见:https://en.wikipedia.org/wiki/Wikipedia:Bypass_your_cache) (4认同)

slm*_*slm 14

Cache-Control如果您在同一个标​​签页中重新加载,Chrome似乎会忽略您的设置.如果您将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
Run Code Online (Sandbox Code Playgroud)

当我在同一个Chrome标签页中不断重新加载它时,它会显示新的时间.

This page rendered at 2014-10-08 13:36:46 -0400.
This page rendered at 2014-10-08 13:36:48 -0400.
Run Code Online (Sandbox Code Playgroud)

标题看起来像这样:

< 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
Run Code Online (Sandbox Code Playgroud)

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

  • 这正是我需要的答案。与 Chrome 争吵了一个小时,试图找出 Cache 标头的正确组合,然后终于找到了这篇文章和 bam,不用担心。 (2认同)

sin*_*pop 13

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

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

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

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

  • 截至 2018 年 6 月 6 日,Chrome 不支持“不可变”标志,您必须使用“max-age=xxx”或其朋友。 (2认同)

小智 11

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

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

  • 我没有检查那个盒子,它仍然没有正确缓存.该框说明:"禁用缓存(当DevTools打开时)". (2认同)

Bey*_*erz 10

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

此错误报告中指出了这一点:https : //bugs.chromium.org/p/chromium/issues/detail?id=110649

  • 这让我发疯……两次!谢谢你!一旦我发现这是问题所在,我就简单地切换到 ngrok,它为您提供了一个有效的通配符 SSL 进行测试,然后我就开始工作了。另外,另一个问题是,如果您在 Chrome DevTools 打开的情况下进行测试,请确保关闭“缓存(当 DevTools 打开时)”设置。 (3认同)