2009-06-08 4 views
3

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

Изображения получены из базы данных.

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

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

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

Edit: По желанию для получения дополнительной информации:

  • 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-проверок. Я разместил решение ниже.

+0

Вы должны направить дополнительную информацию. Иногда браузеры не кэшируют на основе URL-страницы страницы или метаданных, связанных с отображаемой страницей, или, возможно, даже из-за локальных настроек. – Kieveli

+0

Некоторые (я не знаю, кто) также не кэшируют страницы на основе суффиксов, т.е. они не будут кэшировать php-страницы, потому что они, как известно, являются динамическим контентом. –

+0

Очень полезный момент! Я запомню это для любой будущей главы, связанной с кешированием f *** s. – joshcomley

ответ

3

OK, я исправил его.

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

// 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

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

+0

Интересный момент, но это не так (на данный момент, во всяком случае). Благодаря! – joshcomley

+1

На самом деле это не так. Браузеры могут кэшировать контент https, если он имеет заголовок «cache-control: public», в дополнение к стандартному заголовку expires. Firefox определенно будет кэшировать, если видит этот заголовок. – Chi

0

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

  • 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

Не могли бы вы взглянуть на [этот вопрос] (http://stackoverflow.com/questions/19346048/how-to-setup-talifunweb-staticfilehandler-with-a-virtualpathprovider)? – superjos