2010-05-22 39 views
3

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

所以图像有一个这样的URL: http://mydomain/pictures/ajfhajkfhal/44/thumb.jpghttp://mydomain/pictures/ajfhajkfhal/44.jpg

这被改写为: http://mydomain/Picture.aspx?group=ajfhajkfhal&id=44&thumb=thumb.jpghttp://mydomain/Picture.aspx?group=ajfhajkfhal&id=44

我添加缓存规则,当他们到IIS缓存JPG图片请求。这适用于我的磁盘上的真实图像的图像。当通过脚本提供图像时,它们总是通过脚本被请求,而不被缓存。

图像不会经常改变,所以如果缓存至少保存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"; 

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

但这并不能解决问题。我真的认为问题在于Firefox。我使用Firebug来跟踪每个请求,并以某种方式,我认为我正在做一些根本性的错误。正常图像(缓存和静态)会返回响应代码“304(未修改)”,而我的页面总是会返回“200(OK)”。

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

回答

1

如果你所说的“脚本”的意思是在你的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个刻度)
基本上,内容获取缓存但在到达浏览器时到期。

尝试这些:(该TimeSpan.FromMinutes也比new TimeSpan(...)更易读)

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

+0

嗯,该文件,然后缓存服务器端我想,但我喜欢的图像缓存客户端(如果在浏览器中启用),但现在它似乎只缓存静态图像。 – 2010-05-22 19:33:43

+0

@Wim - 您可以通过指定一些http标头来使用客户端缓存。这可以用ASP.NET轻松完成,我编辑了我的答案,告诉你如何。 – Venemo 2010-05-22 20:23:33

+0

@Venemo,这是我试过的。但不知何故,我的Firefox继续重新加载所有的图像,而我在默认缓存设置。当我看看about:cache并检查我的图像是否缓存时,它们就在那里。 我想不管怎样,Firefox总是重新加载这些图像,即使它们被缓存。 我编辑了我的问题,以显示我用来缓存客户端的选项。我认为这是某种浏览器的东西或其他东西。 – 2010-05-23 04:29:16