ASP.net ashx 处理程序不缓存
我们最近安装了 Robohash 作为 Gravatar 的绝佳后备:
http://static2.scirra.net/avatars/128/5df4bf5d460c9497fdb35578e923ad1f.png
如您所见,robohashes 非常出色,并且由我们的静态域提供服务。 URL 实际上被重写了:
<action type="Rewrite" url="gravatar.ashx?hash={R:2}&size={R:1}" appendQueryString="false" />
在同一个 web.config 文件中,我们有缓存配置文件:
<staticContent>
<clientCache httpExpires="Sun, 29 Mar 2020 00:00:00 GMT" cacheControlMode="UseExpires" />
</staticContent>
<caching>
<profiles>
<add extension=".ashx" policy="CacheForTimePeriod" kernelCachePolicy="DontCache" duration="01:00:00" />
<add extension=".png" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
<add extension=".jpg" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
<add extension=".gif" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
<add extension=".ico" policy="CacheUntilChange" kernelCachePolicy="CacheUntilChange" location="Any" />
</profiles>
</caching>
为了在 gravatar.ashx 文件中进行良好的测量,我们还设置了缓存策略:
<%@ WebHandler Language="C#" Class="GravatarImage" %>
using System;
using System.Web;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
public class GravatarImage : IHttpHandler {
public void ProcessRequest (HttpContext context) {
// Adds document content type
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires(DateTime.Now.AddMinutes(60));
context.Response.Cache.SetMaxAge(new TimeSpan(1, 0, 0));
context.Response.AddHeader("Last-Modified", DateTime.Now.ToLongDateString());
// Get params and send initial request to gravatar
string Hash = context.Request.QueryString["hash"];
string Size = context.Request.QueryString["size"];
string URL = "http://www.gravatar.com/avatar/" + Hash + "?r=pg&s=" + Size + "&d=404";
// Make request to gravatar
bool Fetched = makeAvatarRequest(URL);
// Backup to robo hash
if (!Fetched)
{
URL = "http://robohash.org/" + Hash + ".png?size=" + Size + "x" + Size + "&bgset=bg2";
Fetched = makeAvatarRequest(URL);
}
// Fallback if gravatar doesn't match and robohash is down
if (!Fetched)
{
}
// Cache this handler response for 1 hour.
HttpCachePolicy c = context.Response.Cache;
c.SetCacheability(HttpCacheability.Public);
c.SetMaxAge(new TimeSpan(1, 0, 0));
}
// Attempt a request for avatar
private bool makeAvatarRequest(string URL)
{
try
{
WebRequest request = WebRequest.Create(URL);
using (WebResponse response = request.GetResponse())
{
using (Stream responseStream = response.GetResponseStream())
{
displayImage(responseStream);
return true;
}
}
}
catch (WebException ex)
{
return false;
}
}
// Display the image from stream
private void displayImage(Stream stream)
{
HttpContext.Current.Response.ContentType = "image/png";
Image img = Image.FromStream(stream);
MemoryStream temp = new MemoryStream();
img.Save(temp, ImageFormat.Png);
byte[] buffer = temp.GetBuffer();
HttpContext.Current.Response.OutputStream.Write(buffer, 0, buffer.Length);
img.Dispose();
temp.Dispose();
}
public bool IsReusable {
get {
return false;
}
}
}
请注意,我们在底部使用 Response.cache 和 CachePolicy
当我使用 YSlow 时,页面上的每个图像都有一个未来的到期日期,除了这些没有到期日期的头像。每次请求页面时,都会再次获取它们。
该脚本的想法是从外部 URL 获取头像并缓存 1 小时。然后从我们的网站提供。
有人可以帮助我们吗?在没有缓存的情况下使用头像的示例页面是: http://www.scirra.com/forum/construct- in-ludum-dare-21_topic44523.html
因为您使用的是处理程序,所以您需要在自己的代码中处理缓存标头,即也返回 304 响应。因此,请根据文件检查标题上的日期,并在适当的情况下返回 304。
我们在一些图像处理程序的开头有类似于以下的代码,
所使用的两种方法大致如下所示。
Because you are using a handler you need to handle the caching headers in your own code, ie returning the 304 repsonse as well. So check the dates on the headers against the files and return 304's where appropriate.
We have code similar to the following at the start of some our image handlers
the two methods used look roughly as below.