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

StackOverflow https://stackoverflow.com/questions/963123

Вопрос

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

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

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

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 - Не изменено.Всего хорошего!Но сейчас я устанавливаю ETag, используя:

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

Но это не отображается в ответе.Ближе...

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

Это было полезно?

Решение

Хорошо, я это исправил.

Вот что я сделал для всех остальных и для моего собственного использования в будущем:

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

Другие советы

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

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

  • ЭТаг
  • Истекает

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

  • Последнее изменение
  • Если-Совпадение
  • If-None-Совпадение
  • Если-Изменено-С тех пор
  • If-Неизмененный-Поскольку
  • Если только-Не изменено-С тех пор

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

  • ПОЛУЧИТЬ
  • ГОЛОВА

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top