【问题标题】:Expires headers when testing in Chrome在 Chrome 中测试时标头过期
【发布时间】:2009-02-18 05:43:08
【问题描述】:

在这里对“过期”标题感到非常困惑! 有时它会按预期工作 - 有时不会。

我正在使用以下代码来设置过期标头。请注意,这是在 MVC 自定义属性中使用 ASP.NET 完成的 - 这在这里并不真正相关 - 但解释了 'filterContext' 的来源。

HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);

// my own custom header so we know what time it was
filterContext.HttpContext.Response.AddHeader("CurrentTime", DateTime.Now.ToString());

cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");

这有时会给我这样的标题:

Cache-Control: public, must-revalidate, proxy-revalidate, max-age=413
Date: Wed, 18 Feb 2009 05:24:19 GMT
Expires: Wed, 18 Feb 2009 05:21:12 GMT
CurrentTime: 2/17/2009 9:21:12 PM

有时是这样的:

Cache-Control: public, must-revalidate, proxy-revalidate, max-age=600
Date: Wed, 18 Feb 2009 05:27:55 GMT
Expires: Wed, 18 Feb 2009 05:27:55 GMT
CurrentTime: 2/17/2009 9:27:55 PM

我正在通过 Fiddler 运行所有内容,并查看何时重新请求内容以及何时来自浏览器缓存。

现在奇怪的是在 IE 中缓存总是按预期工作。我的 ASP.NET MVC 操作方法的链接出现在 Fiddler 中,然后当我再次单击同一链接时,它来自缓存。

但在 Chrome 中,它有时会,有时不会来自缓存!通过来自缓存,我的意思是没有额外的 HTTP 请求。

例如这样的链接:

 http://ipv4.fiddler:62669/gallery/mainimage/2

将来自 IE 中的缓存,但在 chrome 中返回 200。然后有时在 Chrome 中它确实来自缓存。我已尝试清空浏览器缓存并再次尝试 - 每次结果都相同。

Chrome 是在尝试做一些“聪明”的事情,却惨遭失败 - 还是我需要额外的标题?

我想知道这是否与我的Expires 标题日期实际上永远不会在未来有关。如果我查看 google 的 hosted jQuery file 标题,我会看到标题如下(2010 年到期 - 未来一年)。

Cache-Control: public, max-age=31536000
Date: Wed, 18 Feb 2009 05:44:53 GMT
Expires: Thu, 18 Feb 2010 05:44:53 GMT

Expires 实际上不应该在未来吗??

根据HTTP spec

如果响应同时包含 Expires 标头和 max-age 指令, max-age 指令覆盖 Expires 标头,即使 Expires 标题更具限制性。这条规则 允许源服务器提供, 对于给定的响应,更长的 HTTP/1.1(或 稍后)缓存而不是 HTTP/1.0 缓存。如果某些情况下,这可能很有用 HTTP/1.0 缓存计算不当 年龄或到期时间,可能是由于 去同步时钟。

因此,Chrome 似乎应该尊重 max-age 指令,即使“过期”与当前时间相同,但它似乎并没有这样做。

【问题讨论】:

    标签: google-chrome fiddler


    【解决方案1】:

    我在 ASP.NET MVC 源代码中发现了以下内容:

     public virtual void RenderView(ViewContext viewContext) {
            // TODO: Remove this hack. Without it, the browser appears to always load cached output
            viewContext.HttpContext.Response.Cache.SetExpires(DateTime.Now);
            ViewUserControlContainerPage containerPage = new ViewUserControlContainerPage(this);
            // Tracing requires Page IDs to be unique.
            ID = Guid.NewGuid().ToString();
    
            RenderViewAndRestoreContentType(containerPage, viewContext);
        }
    

    这解释了为什么我的Expires 标头始终是当前时间。但是我真的不认为这是让 Chrome 绊倒的原因,因为我创建了如下最简单的页面,Chrome 仍然很高兴回到服务器并给了我 200

    public partial class test : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            TimeSpan cacheDuration = TimeSpan.FromSeconds(33);
           var cache = Response.Cache;
    
            cache.SetCacheability(HttpCacheability.Public);
            cache.SetExpires(DateTime.Now.Add(cacheDuration));
            cache.SetMaxAge(cacheDuration);
            cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
        }
    }
    

    【讨论】:

    • 我什至将 添加到这个 aspx 页面,并在网络上运行它,它仍然每次返回 200 并更新时间。但在 IE 中它被缓存了 33 秒。搞砸了
    【解决方案2】:

    我几乎已经得出结论,是 Chrome 在缓存方面做了一些非常糟糕的事情。

    我将它简化到尽可能低的级别——从 Google 的服务器获取 jQuery。

    我输入了:

    http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js 
    

    到 Chrome,Fiddler 提出了以下 200 请求:

    Requests started at:    22:58:00:7756
    Responses completed at: 22:58:03:5020
    Total Sequence time:    00:00:02.7263880
    DNS Lookup time:    531ms
    TCP/IP Connect time:    63ms
    
    RESPONSE CODES
    --------------
    HTTP/200:   1
    

    标题如下(注意过期是今天之后的一年):

    Cache-Control: public, max-age=31536000
    Date: Wed, 18 Feb 2009 06:58:01 GMT
    Expires: Thu, 18 Feb 2010 06:58:01 GMT
    Vary: Accept-Encoding
    

    然后我等了几秒钟,然后在同一个选项卡中按回车键。 Fiddler 提出了另一个 **200* 请求:

    Requests started at:    22:58:09:2516
    Responses completed at: 22:58:12:3999
    Total Sequence time:    00:00:03.1482360
    
    RESPONSE CODES
    --------------
    HTTP/200:   1
    

    标题是:

    Cache-Control: public, max-age=31536000
    Date: Wed, 18 Feb 2009 06:58:09 GMT
    Expires: Thu, 18 Feb 2010 06:58:09 GMT
    Vary: Accept-Encoding
    

    显然这不是我所期望的。

    - 两个请求的接受编码相同。

    是的 - 第三个请求给了我一个 304

    这是在我从未做过任何开发的新安装的 Chrome 上 - 我只是第一次安装 Fiddler。

    我等不及有人向我解释这一点。现在我放弃了——我认为我的缓存和过期代码很好。此外,ASP.NET MVC 似乎强制将 Expires 设置为当前时间。这显然不是我的谷歌示例中的一个因素。

    我认为 Chrome 太聪明了,这一定是一个错误 - 我使用的是 1.0.154.48 版本。

    【讨论】:

      猜你喜欢
      • 2012-07-18
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 2014-08-23
      • 1970-01-01
      • 2020-03-18
      • 2014-02-06
      • 2017-11-17
      相关资源
      最近更新 更多