Почему в браузере нет кэшированного изображения? - PullRequest
3 голосов
/ 08 июня 2009

У меня есть пользовательский обработчик, который возвращает изображение в браузер.

Изображения извлекаются из базы данных.

По какой-то причине изображения не кэшируются браузером, и мне было интересно, сможет ли кто-нибудь определить, что мне не хватает, из приведенного ниже кода:

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";

Или, в качестве альтернативы, если я как-то упускаю суть, и мне нужно поискать где-то еще.

Редактировать: Согласно запросу для получения дополнительной информации:

  • URL-адрес всегда один и тот же
  • Я тестирую загрузку одного и того же файла через стандартный канал IIS и мой канал в одном браузере на одном компьютере. Тот, который загружается через IIS, обычно кэшируется, мой файл - нет.

Редактировать 2: После проверки запросов / ответов HTTP на обычном маршруте IIS я думаю, что это как-то связано с ETag. ETag (который я новичок на данный момент), кажется, своего рода контрольная сумма для документа. При последующих запросах от браузера ETag отправляется, и если сервер обнаруживает, что ETag не изменился, он возвращает 304 - Not Modified. Все хорошо! Но сейчас я устанавливаю ETag, используя:

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

Но оно не появляется в ответе. Ближе ...

Редактировать 3: Я исправил это в конце после использования Firebug для некоторой забавы по проверке HTTP. Я разместил свое решение ниже.

Ответы [ 3 ]

3 голосов
/ 08 июня 2009

ОК, я исправил.

Вот что я сделал для кого-то другого и для своей будущей ссылки:

// 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% полагаться на строку даты для определения, является ли изображение новым или нет (в моем конкретном сценарии).

0 голосов
/ 18 февраля 2010

При генерации ответа вам нужно беспокоиться:

  • ETag
  • Истекает

При получении запроса вам нужно беспокоиться:

  • Last-Modified
  • If-Match
  • If-None-Match
  • If-Modified-Since
  • If-Unmodified-С
  • Если только-Modified-Since

Возможно, вам также придется позаботиться о следующих методах http:

  • GET
  • ГОЛОВА

Вот решение, которое должно быть достаточно легко реорганизовано для удовлетворения ваших потребностей: http://code.google.com/p/talifun-web/wiki/StaticFileHandler

Он читает файлы из файловой системы и помещает их в кэш-память, поэтому просто измените их на чтение из базы данных. Должно быть легкой работой.

0 голосов
/ 08 июня 2009

Вы ничего не упоминаете в своем посте об этом, но это адрес https: //? Браузеры не кэшируют изображения и страницы с сайтов https по соображениям безопасности.

...