Я работаю над веб-приложением в ASP.NET 2.0, которое включает обслуживание изображений через обработчик ресурсов (.ashx). Я только что реализовал обработку заголовков кэша и условных запросов GET, чтобы мне не приходилось обслуживать все изображения для каждого запроса. Но я не уверен, что полностью понимаю, что происходит с кешем браузера.
Изображения извлекаются через URL, например 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.