Question

J'ai un gestionnaire personnalisé qui retourne une image au navigateur.

Les images sont extraites d'une base de données.

Pour une raison quelconque les images ne sont pas mises en cache par le navigateur, et je me demandais si quelqu'un pourrait être en mesure de repérer ce que je suis absent du code ci-dessous:

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 bien si je suis tout à fait en quelque sorte le point manquant et il y a un autre endroit que je dois regarder.

Modifier: Selon la demande pour plus d'informations:

  • L'URL est toujours le même
  • Je teste le chargement du même fichier via le tuyau standard IIS et ma pipe dans le même navigateur sur le même PC. Celui qui se charge via IIS est normalement mis en cache, mon dossier est pas.

Edit 2: Après avoir inspecté les requêtes HTTP / réponses sur la route IIS normale, je pense qu'il a quelque chose à voir avec le ETag. Le ETag (que je suis nouveau comme tout à l'heure) semble être une sorte de contrôle du document. Pour les requêtes suivantes par un navigateur, le ETag est envoyé et si le serveur trouve le ETag n'a pas changé, alors il retourne un 304 - Non modifié. Tout bon! Mais je suis en train de mettre le ETag en utilisant:

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

Mais il ne semble pas dans la réponse. Plus près ...

Modifier 3: Je l'ai fixé à la fin après avoir profité de Firebug pour une inspection HTTP amusant. J'ai posté ma solution ci-dessous.

Était-ce utile?

La solution

OK, je l'ai fixé.

Voici ce que je l'ai fait pour quelqu'un d'autre et pour ma propre référence future:

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

Œuvres un charme!

Si quelqu'un voit des problèmes potentiels ici, laissez-moi savoir si je peux mettre à jour ce sujet.

Pour préempter une évidente un -. Je peux compter sur 100% de la chaîne de date pour identifier si une image est nouvelle ou non (dans mon scénario particulier)

Autres conseils

Vous ne mentionnez rien dans votre post à ce sujet, mais est-ce une adresse https: //? Les navigateurs ne cache pas les images et les pages des sites https pour des raisons de sécurité.

Les choses dont vous avez besoin à vous soucier de la génération de la réponse sont:

  • ETag
  • Expires

Les choses que vous devez à vous soucier de la réception d'une demande sont:

  • Last-Modified
  • Si-Match
  • If-None-Match
  • Si-Modified-Since
  • Si-Unmodified-Since
  • -Since À moins-Modified

Vous pourriez aussi avoir besoin de se soucier des méthodes HTTP suivantes:

  • GET
  • HEAD

Voici une solution qui devrait être assez facile à factoriser à la suite vos besoins: http://code.google.com/p/talifun-web/wiki/ StaticFileHandler

Il lit les fichiers du système de fichiers et les place dans un les cache en mémoire, il suffit de changer pour lire la base de données. Devrait être une tâche facile.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top