Désactivation de la mise en cache du navigateur pour tous les navigateurs à partir d'ASP.NET

87

Je suis à la recherche d'une référence définitive au code ASP.NET requis pour désactiver la mise en cache de la page par les navigateurs. Il existe de nombreuses façons d'affecter les en-têtes HTTP et les balises méta et j'ai l'impression que différents paramètres sont nécessaires pour que différents navigateurs se comportent correctement. Ce serait vraiment génial d'obtenir un morceau de code de référence commenté pour indiquer ce qui fonctionne pour tous les navigateurs et ce qui est requis pour un navigateur particulier, y compris les versions.

Il existe une énorme quantité d'informations sur ce problème, mais je n'ai pas encore trouvé de bonne référence décrivant les avantages de chaque méthode et indiquant si une technique particulière a été remplacée par une API de niveau supérieur.

Je suis particulièrement intéressé par ASP.NET 3.5 SP1, mais il serait également bon d'obtenir des réponses pour la version antérieure.

Cette entrée de blog Deux différences importantes entre Firefox et la mise en cache IE décrit certaines différences de comportement du protocole HTTP.

L'exemple de code suivant illustre le genre de chose qui m'intéresse

public abstract class NoCacheBasePage : System.Web.UI.Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        DisableClientCaching();
    }

    private void DisableClientCaching()
    {
        // Do any of these result in META tags e.g. <META HTTP-EQUIV="Expire" CONTENT="-1">
        // HTTP Headers or both?

        // Does this only work for IE?
        Response.Cache.SetCacheability(HttpCacheability.NoCache);

        // Is this required for FireFox? Would be good to do this without magic strings.
        // Won't it overwrite the previous setting
        Response.Headers.Add("Cache-Control", "no-cache, no-store");

        // Why is it necessary to explicitly call SetExpires. Presume it is still better than calling
        // Response.Headers.Add( directly
        Response.Cache.SetExpires(DateTime.UtcNow.AddYears(-1));
    }
}
Martin Hollingsworth
la source
5
J'essaierais de répondre si je ne savais pas à quel point ta tâche est horriblement impossible. Contrôler le cache du client, c'est comme essayer d'utiliser des baguettes de 10 pieds de long pour réorganiser les meubles.
Jeff Meatball Yang
Un grand nombre de réponses qui ne couvrent qu'une partie du problème seraient encore très utiles. Veuillez ajouter votre valeur de 2 cents.
Martin Hollingsworth

Réponses:

96

Voici ce que nous utilisons dans ASP.NET:

// Stop Caching in IE
Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);

// Stop Caching in Firefox
Response.Cache.SetNoStore();

Il arrête la mise en cache dans Firefox et IE, mais nous n'avons pas essayé d'autres navigateurs. Les en-têtes de réponse suivants sont ajoutés par ces instructions:

Cache-Control: no-cache, no-store
Pragma: no-cache
HttpWatchSupport
la source
5
+1 Cela fonctionne pour moi dans Chrome, merci beaucoup. J'utilise également Response.Cache.SetAllowResponseInBrowserHistory (true); pour éviter l'historique pour stocker une entrée pour chaque requête de la même page.
daniloquio
12
Apparemment, quelqu'un a découvert que l'utilisation de SetCacheability avec NoCache désactive également le cache de sortie ASP.NET (cache côté serveur). Ils suggèrent d'utiliser plutôt l'option ServerAndNoCache. codeclimber.net.nz/archive/2007/04/01/…
md1337
1
Pour clarifier les commentaires dans l'extrait de code, la méthode principale est SetCacheability. SetNoStoreest une solution de contournement IE6. Voir Pourquoi les deux no-cache et no-store devraient être utilisés dans la réponse HTTP? .
Edward Brey
3
FWIW ... nécessaire pour ajouter SetNoStore pour IE10
felickz
Pour ceux qui liront cette page qui produiront des PDF dynamiques sur https et définiront les en-têtes de cache comme celui-ci, veuillez vous méfier du bogue IE8 et inférieur suivant: stackoverflow.com/questions/1038707/…
Paddy
41

Pour ce que ça vaut, je devais simplement gérer cela dans mon application ASP.NET MVC 3. Voici le bloc de code que j'ai utilisé dans le fichier Global.asax pour gérer cela pour toutes les demandes.

    protected void Application_BeginRequest()
    {
        //NOTE: Stopping IE from being a caching whore
        HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();
        Response.Cache.SetExpires(DateTime.Now);
        Response.Cache.SetValidUntilExpires(true);
    }
Adam Carr
la source
Le HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false)fait la différence pour empêcher la mise en cache dans bith IE et FireFox
Michael Kniskern
2
-1, le réglage dans ces Application_BeginRequest () provoque l'envoi des en-têtes sans cache pour les éléments que vous voudrez probablement mettre en cache (fichiers JavaScript, images, etc.). Je ne l'ai pas encore essayé, mais l'emplacement de l'OP (définir les en-têtes dans la page ASP elle-même) est probablement meilleur.
Evan Haas du
Je m'attendais à ce que cette réponse fonctionne car c'est le moyen le plus soigné de la définir dans glabal.asax mais pas encore de joie
lawphotog
5
@Evan, Application_BeginRequest ne sera appelée que pour les demandes envoyées d'IIS vers ASP.NET. Souvent, les fichiers statiques tels que CSS, JS, images, polices, etc. sont des extensions qui sont considérées comme des fichiers statiques d'IIS et qui ne sont pas envoyées au Runtime ASP.NET. Si IIS est configuré pour envoyer toutes les demandes au runtime ASP.NET, alors oui, cela s'appliquerait à toutes les demandes, même si les fichiers sont statiques et doivent être mis en cache.
Adam Carr
@Adam, ça a du sens. J'annulerais mon -1 mais SO dit que mon vote est verrouillé :-(
Evan Haas
2

J'ai essayé diverses combinaisons et les ai fait échouer dans FireFox. Cela fait un moment donc la réponse ci-dessus peut fonctionner correctement ou j'ai peut-être manqué quelque chose.

Ce qui a toujours fonctionné pour moi, c'est d'ajouter ce qui suit à l'en-tête de chaque page, ou le modèle (Master Page en .net).

<script language="javascript" type="text/javascript">
    window.onbeforeunload = function () {   
        // This function does nothing.  It won't spawn a confirmation dialog   
        // But it will ensure that the page is not cached by the browser.
    }  
</script>

Cela a désactivé toute la mise en cache dans tous les navigateurs pour moi sans faute.

Steve
la source
7
Je ne sais pas ce que cela est censé faire, mais cela ressemble à un gros hack qui est voué à l'échec dans la prochaine mise à jour de l'un de ces navigateurs.
md1337
C'est expliqué par exemple sur web.archive.org/web/20160112095216/http://www.hunlock.com/blogs/… - en résumé, l'événement onbeforeunload a été implémenté pour être utilisé par les banques et empêche la page d'être mise en cache.
ChrisW
1

Il y a deux approches que je connais. La première consiste à dire au navigateur de ne pas mettre la page en cache. Définir la réponse sur aucun cache prend en charge cela, mais comme vous pensez que le navigateur ignorera souvent cette directive. L'autre approche consiste à définir la date et l'heure de votre réponse à un point dans le futur. Je pense que tous les navigateurs corrigeront cela à l'heure actuelle lorsqu'ils ajoutent la page au cache, mais cela affichera la page comme plus récente lorsque la comparaison sera effectuée. Je crois qu'il peut y avoir des cas où aucune comparaison n'est faite. Je ne suis pas sûr des détails et ils changent à chaque nouvelle version du navigateur. Note finale J'ai eu plus de chance avec les pages qui se «rafraîchissent» (une autre directive de réponse). L'actualisation semble moins susceptible de provenir du cache.

J'espère que ça t'as aidé.

Pat O
la source
0

Je vais tester l'ajout de la balise no-store sur notre site pour voir si cela fait une différence dans la mise en cache du navigateur (Chrome a parfois mis les pages en cache). J'ai également trouvé cet article très utile sur la documentation sur comment et pourquoi la mise en cache fonctionne et j'examinerai ensuite ETag si le no-store n'est pas fiable:

http://www.mnot.net/cache_docs/

http://en.wikipedia.org/wiki/HTTP_ETag

Le codeur
la source