Perché mia abitudine non viene recapitato immagine caching nel browser?
-
12-09-2019 - |
Domanda
Ho un gestore personalizzato che restituisce un'immagine al browser.
Le immagini vengono recuperati da un database.
Per qualche ragione le immagini non sono memorizzati nella cache dal browser, e mi chiedevo se qualcuno potrebbe essere in grado di individuare ciò che mi manca dal codice qui sotto:
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";
In alternativa, se mi manca completamente il punto in qualche modo e non c'è un altro posto ho bisogno di guardare.
Modifica Secondo la richiesta per ulteriori informazioni:
- l'URL è sempre la stessa
- sto testando caricare lo stesso file tramite tubo di IIS di serie e la pipa nello stesso browser sullo stesso PC. Quello che carica tramite IIS normalmente viene memorizzata nella cache, il mio file non è.
Modifica 2: Dopo aver ispezionato le richieste HTTP / risposte sul normale percorso di IIS Credo che abbia qualcosa a che fare con l'ETag. L'ETag (che sono nuovo a partire da questo momento) sembra essere una sorta di checksum per il documento. Alle successive richieste da parte di un browser ETag viene inviato e se il server trova l'ETag non è cambiato poi restituisce un 304 - Not Modified. Tutto bene! Ma ora sto impostando l'ETag utilizzando:
HttpContext.Current.Response.Cache.SetETag(imgRepGetCache.DateCached.ToString());
Ma non appare nella risposta. Più vicino ...
Modifica 3: I risolto alla fine, dopo approfittando di Firebug per un certo divertimento HTTP ispezione. Ho pubblicato la mia soluzione qui di seguito.
Soluzione
OK, ho riparato.
Ecco quello che ho fatto per chiunque altro e per il mio riferimento futuro:
// 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
}
Funziona un fascino!
Se qualcuno ha visto eventuali problemi qui, me lo faccia sapere, così posso aggiornare questo.
Per anticipare un ovvio -. Posso contare al 100% sulla corda data identificare se un'immagine è nuovo o meno (nel mio scenario particolare)
Altri suggerimenti
Non accennate nulla nel vostro post su di esso, ma è questo un https: // indirizzo? I browser non nascondono le immagini e le pagine da https siti per motivi di sicurezza.
Le cose che dovete preoccupare nella generazione della risposta sono:
- ETag
- Scade
Le cose che avete bisogno di preoccuparsi quando si riceve una richiesta sono:
- Last-Modified
- Se-Match
- If-None-Match
- If-Modified-Since
- Se-non modificato-Since
- A meno-Modified-Since
Si potrebbe anche bisogno di preoccuparsi per i seguenti metodi HTTP:
- GET
- HEAD
Ecco una soluzione che dovrebbe essere piuttosto facile refactoring per la tua vacanza: http://code.google.com/p/talifun-web/wiki/ StaticFileHandler
Si legge i file dal file system e li li pone in una cache in memoria, quindi basta cambiare leggere dal database. Dovrebbe essere un lavoro facile.