为什么我的自定义交付图像缓存不在浏览器中?

时间:2009-06-08 00:50:20

标签: image caching response httpmodule handler

我有一个自定义处理程序,它将图像返回给浏览器。

从数据库中提取图像。

由于某种原因,浏览器没有缓存图像,我想知道是否有人能够从下面的代码中找到我遗漏的内容:

HttpContext.Current.Response.BinaryWrite(imageBytes);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.Public);
Context.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);
if(imgRepGetCache.DateCached.HasValue)
    HttpContext.Current.Response.Cache.SetLastModified(imgRepGetCache.DateCached.Value);
HttpContext.Current.Response.Cache.SetExpires(DateTime.Now.AddDays(2));
HttpContext.Current.Response.ContentType = "image/jpeg";

或者,如果我以某种方式完全忽略了这一点,那么我需要在其他地方看一下。

编辑:根据要求提供更多信息:

  • 网址始终相同
  • 我正在测试通过标准IIS管道和我的管道在同一台PC上的同一浏览器中加载相同的文件。通常通过IIS加载的那个是缓存的,我的文件不是。

编辑2:在检查正常IIS路由上的HTTP请求/响应后,我认为它与ETag有关。 ETag(我刚才是新手)似乎是文档的一种校验和。在浏览器的后续请求中,ETag被发送,并且如果服务器发现ETag没有改变,则它返回304-未修改。都好!但我现在正在设置ETag:

HttpContext.Current.Response.Cache.SetETag(imgRepGetCache.DateCached.ToString());

但它没有出现在回复中。更靠近...

编辑3:我在利用Firebug进行一些HTTP检查之后最终修复了它。我在下面发布了我的解决方案。

3 个答案:

答案 0 :(得分:3)

好的,我修好了。

以下是我为其他人所做的事情以及我将来的参考:

// Check for repeated request for the same image from a browser
if (HttpContext.Current.Request.Headers.Get("If-None-Match") == imgRepGetCache.DateCached.Value.ToString())
{
    // Return 304 - Not Modified
    HttpContext.Current.Response.Status = "304 Not Modified";
}
else
{
    if (imgRepGetCache.DateCached.HasValue)
        HttpContext.Current.Response.Headers.Set("Etag", imgRepGetCache.DateCached.Value.ToString());
    // ... do my other stuff here
}

有魅力!

如果有人发现任何潜在的问题,请告诉我,以便我可以更新。

为了抢先一个明显的 - 我可以100%依靠日期字符串来识别图像是否是新的(在我的特定场景中)。

答案 1 :(得分:0)

您的帖子中没有提及任何内容,但这是https://地址吗?由于安全原因,浏览器不会从https站点缓存图像和页面。

答案 2 :(得分:0)

在生成响应时需要担心的事情是:

  • ETag
  • 到期

接收请求时需要担心的事情是:

  • 上次修改
  • 如果-匹配
  • 如果-无 - 匹配
  • 如果-Modified-Since的
  • 如果未改性的-由于
  • 除非-Modified-Since的

您可能还需要担心以下http方法:

  • GET
  • HEAD

这是一个解决方案,应该很容易重构以满足您的需求: http://code.google.com/p/talifun-web/wiki/StaticFileHandler

它从文件系统中读取文件并将它们放入内存中的缓存中,因此只需将其更改为从数据库中读取即可。应该是一件容易的事。