Pregunta

Tengo un controlador personalizado que está devolviendo una imagen al navegador.

Las imágenes se obtienen de una base de datos.

Por alguna razón, las imágenes no se almacena en caché por el navegador, y me preguntaba si alguien podría ser capaz de detectar lo que me falta desde el código de abajo:

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

O, alternativamente, si me falta por completo el punto de alguna manera y no hay otro lugar tengo que mirar.

Editar: Según la petición para obtener más información:

  • El URL es siempre el mismo
  • Estoy probando cargar el mismo archivo a través de la tubería de IIS estándar y la pipa en el mismo navegador en el mismo PC. El que carga a través de IIS normalmente se almacena en caché, mi archivo no lo es.

Editar 2: Después de inspeccionar las peticiones HTTP / respuestas en la ruta normal de IIS Creo que tiene algo que ver con la ETag. El ETag (que soy nuevo a partir de ahora) parece ser una especie de suma de comprobación para el documento. En las solicitudes posteriores de un navegador de la ETag es enviado y si el servidor encuentra la ETag no ha cambiado entonces se devuelve un 304 - No modificado. ¡Todo bien! Pero ahora estoy estableciendo el ETag usando:

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

Sin embargo, no aparece en la respuesta. Más cerca ...

Editar 3: I fijado en el final después de tomar ventaja de Firebug para algunos HTTP inspección de diversión. He publicado mi solución a continuación.

¿Fue útil?

Solución

OK, lo arreglé.

Esto es lo que hice para nadie y para mi propia referencia 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 a las mil maravillas!

Si alguien ve a cualquier problema potencial aquí, que me haga saber para que pueda actualizar esta.

Para adelantarse a una obvia -. Puedo 100% confiar en la cadena de fecha para identificar si una imagen es nueva o no (en mi escenario particular)

Otros consejos

Usted no menciona nada en su post sobre ello, pero este es un https: // dirección? Los navegadores no hacen caché de imágenes y páginas de sitios https debido a razones de seguridad.

Las cosas que hay que preocuparse en la generación de la respuesta son:

  • ETag
  • Expira

Las cosas que tiene que preocuparse cuando se recibe una solicitud son:

  • Last-Modified
  • If-Match
  • Si-None-Match
  • Si-Modified-Since
  • Si-no modificado-Desde
  • A menos-Modified-Since

También podría ser necesario que preocuparse de los siguientes métodos http:

  • GET
  • CABEZA

Esta es una solución que debería ser bastante fácil de refactorizar a la habitación sus necesidades: http://code.google.com/p/talifun-web/wiki/ StaticFileHandler

Se lee los archivos del sistema de archivos y los los coloca en una memoria caché en la memoria, por lo que sólo cambiarlo para leer desde la base de datos. En caso de ser un trabajo fácil.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top