ASP.NET中与HTTP缓存相关的标头的有效含义

时间:2012-01-27 17:27:10

标签: asp.net http caching

我正在使用ASP.NET 2.0中的Web应用程序,该应用程序涉及通过资源处理程序(.ashx)提供图像。我刚刚实现了处理缓存头和条件GET请求,因此我不必为每个请求提供所有图像。但我不确定我是否完全理解浏览器的缓存正在发生什么。

图像是通过http://www.mysite.com/image.ashx?imageID=3等网址获取的。我在处理程序中的代码看起来像这样:

int imageID = -1;
try
{
  imageID = Int32.Parse(context.Request["imageID"]);
}
catch (Exception) {}

MyImageClass image = DataLayer.GetImage(imageID);
if (image != null)
{
  DateTime requestedDate = DateTime.MinValue;
  if (context.Request.Headers["If-Modified-Since"] != null)
  {
    requestedDate = DateTime.Parse(context.Request.Headers["If-Modified-Since"])
      .ToLocalTime();
  }

  if (requestedDate < image.ModifiedDate)
  {
     context.Response.AddHeader("content-type", image.ContentType);
     context.Response.CacheControl = HttpCacheability.Private.ToString();
     context.Response.Cache.SetLastModified(image.ModifiedDate.ToUniversalTime());
     context.Response.Cache.SetMaxAge(TimeSpan.FromDays(1));
     //write image to output stream
  }
  else
  {
    context.Response.StatusDescription = "Not Modified";
    context.Response.StatusCode = 304;
  }
}

这是第一次请求图像时响应标头的样子:

HTTP/1.1 200 OK
Cache-Control: private, max-age=86400
Content-Length: 1048576
Content-Type: image/jpeg
Expires: Sat, 28 Jan 2012 17:17:11 GMT
Last-Modified: Fri, 27 Jan 2012 16:50:27 GMT
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Fri, 27 Jan 2012 17:17:10 GMT

这是对后续请求的回应:

HTTP/1.1 304 Not Modified
Cache-Control: private
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
X-Powered-By: ASP.NET
Date: Fri, 27 Jan 2012 17:17:30 GMT
Connection: close

在Fiddler中观察请求时,我注意到浏览器(Firefox 9)在第一次请求后总是对图像发出条件GET请求。它获得304 Not Modified响应并从缓存中提取图像,这很棒。但是,在标题的最大年龄(或失效日期)过去之后,是否有办法让它始终从缓存中拉出来,甚至不询问服务器?我已尝试将context.Response.Cache.SetExpires()与未来日期一起使用,浏览器仍会发出条件GET请求。

3 个答案:

答案 0 :(得分:3)

当您按 F5 或重新加载时,Firefox将始终发送条件请求。

如果您正常导航到该页面(例如,点击链接或使用地址栏),它将直接进入缓存。

答案 1 :(得分:2)

静态资源处理程序在表面看起来非常简单,但说实话它不适合胆小的人 - 并不意味着你是一个人,我只是说它更多工作比那几行

您必须考虑HTTP提供的所有可能性。您的一个概念是电子标签

除了过期等,您还必须容纳所有这些HTTP请求标头:

If-Match
If-Modified-Since
If-None-Match
If-Range
If-Unmodified-Since

我会把它留给框架去做。

我意识到你必须自己做这一切。我将看看静态文件处理程序的实现以及它如何实现所有这些。

更新

看看这个sample

答案 2 :(得分:0)

没有HTTP标头可以保证任何缓存行为。

Expires标头指示客户端所有对同一URI的查询无意义的日期。但是任何HTTP客户端都可能遵守它而不是。

此外,当您点击F5或重新加载或刷新时,几乎所有浏览器都会重新查询所有页面资源。