在Chrome中进行测试时会过期标题

时间:2009-02-18 05:43:09

标签: google-chrome fiddler

在这里对'Expires'标题感到非常困惑! 有时候它按预期工作 - 有时候没有。

我使用以下代码设置过期标头。请注意,这是使用ASP.NET在MVC自定义属性中完成的 - 这在这里并不相关 - 但解释了'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中的缓存,但回来时带有200 in chrome。然后有时在Chrome中,它来自缓存。我已经尝试清空浏览器缓存并再次尝试 - 每次都是相同的结果。

Chrome是否正在尝试做一些“聪明”的事情而且只是惨遭失败 - 或者我是否需要额外的标题?

我想知道的是,它是否与我Expires标题日期实际上未来的事实有关。如果我查看谷歌的标题为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

不应该过期实际到期吗?

根据HTTP spec

  

如果回复包含过期   header和max-age指令,   max-age指令覆盖了   过期标题,即使过期   标题更具限制性。这个规则   允许原始服务器提供,   对于给定的响应,更长   到期时间到HTTP / 1.1(或   缓存而不是HTTP / 1.0   缓存。如果确定,这可能很有用   HTTP / 1.0缓存不正确地计算   年龄或到期时间,也许是到期日   去同步时钟。

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

2 个答案:

答案 0 :(得分:3)

我在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");
    }
}

答案 1 :(得分:1)

我已经得出结论,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

标题如下(注意Expires是今天之后的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

显然这不是我所期待的。

- 两个请求的Accept-Encoding相同。

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

这是一个新的Chrome安装程序,我从来没有进行过任何开发 - 而且我只是第一次安装了Fiddler。

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

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