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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top