【问题标题】:Effective meaning of HTTP cache-related headers in ASP.NETASP.NET中HTTP缓存相关标头的有效含义
【发布时间】:2012-02-20 16:29:07
【问题描述】:

我正在开发 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 请求。

【问题讨论】:

  • 你应该调用TryParse而不是使用catch
  • @Slaks - 很好,我以后会这样做。

标签: asp.net http caching


【解决方案1】:

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

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

【讨论】:

  • 当缓存过期时(根据头部内容),它会再次发送条件获取吗?
【解决方案2】:

静态资源处理程序在表面上看起来很简单,但老实说它不适合胆小的人 - 并不是说​​你是其中之一,我只是说它更多比那几行更有效

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

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

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

我会把它留给框架去做。

我知道你必须自己做这一切。我会看看静态文件处理程序的实现以及它是如何实现这一切的。

更新

看看这个sample

【讨论】:

  • 如何将其留给框架?您是说将图像存储在文件系统中而不是数据库中,还是有办法让框架处理缓存内容,将图像存储在 SQL 服务器中并作为二进制流提供服务?
  • 该示例似乎适用于较新版本的 .NET;我在 ASP.NET 2.0 上运行。另外,我的想法是否正确,因为电子标签是 optional,所以不使用它或其关联的标头没有直接的缺点吗?
  • 后续问题发布here
【解决方案3】:

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

Expires 标头指示客户端在该日期之前对同一 URI 的所有查询均无意义。但任何 HTTP 客户端都可能服从它,也可能不服从。

此外,当您按 F5 或重新加载或刷新时,几乎所有浏览器都会请求所有页面资源。

【讨论】:

    猜你喜欢
    • 2011-12-03
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 2010-10-31
    • 1970-01-01
    • 2012-12-19
    • 2016-06-29
    • 2011-01-28
    相关资源
    最近更新 更多