Почему мое пользовательское изображение не кэшируется в браузере?
-
12-09-2019 - |
Вопрос
У меня есть пользовательский обработчик, который возвращает изображение в браузер.
Изображения извлекаются из базы данных.
По какой-то причине изображения не кэшируются браузером, и мне было интересно, сможет ли кто-нибудь определить, чего мне не хватает в приведенном ниже коде:
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
Он считывает файлы из файловой системы и помещает их в кэш в памяти, поэтому просто измените его на чтение из базы данных.Это должна быть легкая работа.