Por que meu costume não é entregue caching imagem no navegador?
-
12-09-2019 - |
Pergunta
Eu tenho um manipulador personalizado que está retornando uma imagem para o navegador.
As imagens são obtidas a partir de um banco de dados.
Por alguma razão as imagens não estão sendo armazenados em cache pelo navegador, e eu queria saber se alguém pode ser capaz de detectar o que estou ausente do código abaixo:
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";
Ou, alternativamente, se eu estou faltando completamente o ponto de alguma forma e não há necessidade I algum outro lugar para olhar.
Editar: Como pelo pedido para mais informações:
- A URL é sempre a mesma
- Eu estou testando a carregar o mesmo arquivo via tubulação IIS padrão e meu cachimbo no mesmo navegador no mesmo PC. Aquele que carrega através do IIS normalmente é armazenado em cache, o meu arquivo não é.
Editar 2: Depois de inspecionar as solicitações HTTP / respostas na rota IIS normal, eu acho que tem algo a ver com o ETag. O ETag (que eu sou novo para a partir de agora) parece ser uma espécie de soma de verificação para o documento. Em solicitações subseqüentes por um navegador da ETag é enviado e se os achados servidor do ETag não mudou em seguida, ele retorna um 304 - Não modificado. Tudo bom! Mas agora estou definindo o ETag usando:
HttpContext.Current.Response.Cache.SetETag(imgRepGetCache.DateCached.ToString());
Mas ele não aparece na resposta. Mais perto ...
Editar 3: Eu fixo-lo no final depois de tomar vantagem de Firebug por algum HTTP inspecionar divertido. Eu postei a minha solução abaixo.
Solução
OK, eu fixa-lo.
Aqui está o que eu fiz para ninguém e para minha própria referência futura:
// 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
}
Funciona um encanto!
Se alguém manchas eventuais problemas aqui, me avise para que eu possa atualizar esta.
Para antecipar-se um exemplo óbvio -. Posso 100% contam com a seqüência de data para identificar se uma imagem é novo ou não (no meu cenário particular)
Outras dicas
Você não mencionou nada em seu post sobre isso, mas este é um https: // endereço? Navegadores não imagens de cache e páginas de sites HTTPS devido a razões de segurança.
As coisas que você precisa se preocupar com a geração da resposta são:
- ETag
- Expira
As coisas que você precisa se preocupar quando receber um pedido são:
- Last-Modified
- Se-Match
- If-None-Match
- If-Modified-Since
- Se-Unmodified-Since
- A menos-Modified-Since
Você também pode precisar se preocupar com os seguintes métodos http:
- GET
- CABEÇA
Aqui é uma solução que deve ser bastante fácil de refatorar que atendam às suas necessidades: http://code.google.com/p/talifun-web/wiki/ StaticFileHandler
Ele lê arquivos do sistema de arquivos e os coloca-los em um cache na memória, então, basta alterá-lo para ler a partir de banco de dados. Deve ser uma tarefa fácil.