缓存通过脚本提供的图像

时间:2010-05-22 13:06:59

标签: c# .net asp.net iis-7 caching

我有一个脚本,它通过使用几个查询字符串变量来提供图像。我也在IIS 7.5中使用URL重写。

因此图片的网址如下: http://mydomain/pictures/ajfhajkfhal/44/thumb.jpg 要么 http://mydomain/pictures/ajfhajkfhal/44.jpg

这被重写为: http://mydomain/Picture.aspx?group=ajfhajkfhal&id=44&thumb=thumb.jpg 要么 http://mydomain/Picture.aspx?group=ajfhajkfhal&id=44

我向IIS添加了缓存规则,以便在请求时缓存JPG图像。这适用于我的磁盘上的REAL图像。当通过脚本提供图像时,它们总是通过脚本被请求,而不是被缓存。

图像不会经常更改,因此如果缓存至少保留30分钟(或直到文件更改),那将是最好的。

我在我的网站上使用.NET / C#4.0。我尝试在C#中设置多个缓存选项,但我似乎无法找到如何缓存这些图像(客户端),而我的静态图像正确缓存。

编辑我使用以下选项在客户端缓存图像,其中'fileName'是图像的物理文件名(在磁盘上)。

context.Response.AddFileDependency(fileName);
context.Response.Cache.SetETagFromFileDependencies();
context.Response.Cache.SetLastModifiedFromFileDependencies();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddTicks(600));
context.Response.Cache.SetMaxAge(new TimeSpan(0, 5, 0));
context.Response.Cache.SetSlidingExpiration(true);
context.Response.Cache.SetValidUntilExpires(true);
context.Response.ContentType = "image/jpg";

编辑2 感谢您指出这一点,这确实是一个非常愚蠢的错误;)。我从现在开始将它改为30分钟(DateTime.Now.AddMinutes(30))。

但这并没有解决问题。我真的认为问题在于Firefox。我使用Firebug跟踪每个请求,不知何故,我在想我正在做一些根本错误的事情。正常图像(缓存和静态)返回响应代码“304(未修改)”,而我的页面总是返回“200(OK)”。

alt text http://images.depl0y.com/capture.jpg

1 个答案:

答案 0 :(得分:1)

如果“script”的含义是Picture.aspx中的代码,我应该指出C#不是脚本语言,因此技术上不是脚本。

您可以使用ASP.NET提供的缓存API 我假设你已经有一个包含这样的方法。以下是如何使用缓存API:

string fileName = ... // The name of your file
byte[] bytes = null;

if (HttpContext.Current.Cache[fileName] != null)
{
    bytes = (byte[])HttpContext.Current.Cache[fileName];
}
else
{
    bytes = ... // Retrieve your image's bytes
    HttpContext.Current.Cache[fileName] = bytes; // Set the cache
}

// Send it to the client
Response.BinaryWrite(bytes);
Response.Flush();

请注意,您在缓存中使用的密钥必须对每个缓存项都是唯一的,因此仅为此目的使用文件名可能是不够的。

修改

如果要在客户端启用缓存内容,请使用以下命令:

Response.Cache.SetCacheability(HttpCacheability.Public);

您可以尝试使用不同的HttpCacheability值。有了这个,您可以指定缓存内容的方式和位置。 (例如,在服务器上,代理服务器上和客户端上)

这将使ASP.NET向客户端发送具有相应HTTP头的缓存规则 这并不能保证客户端会实际缓存它(例如,它取决于浏览器设置),但它会告诉浏览器“你应该缓存它!”

最佳做法是在客户端和服务器端使用缓存。

编辑2:

您的代码存在问题SetExpires(DateTime.Now.AddTicks(600))。 600蜱只是一小部分......(1秒= 10000000蜱)
基本上,内容会被缓存,但到达浏览器的那一刻就会过期。

试试这些:

context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(5));
context.Response.Cache.SetMaxAge(TimeSpan.FromMinutes(5));

TimeSpan.FromMinutes也比new TimeSpan(...)更具可读性。)