Comment contrôlons-nous la mise en cache des pages Web, dans tous les navigateurs?


1552

Nos enquêtes nous ont montré que tous les navigateurs ne respectent pas les directives de cache HTTP de manière uniforme.

Pour des raisons de sécurité , nous ne voulons pas certaines pages de notre application à être mises en cache, jamais, par le navigateur Web. Cela doit fonctionner pour au moins les navigateurs suivants:

  • Internet Explorer 6+
  • Firefox 1.5+
  • Safari 3+
  • Opera 9+
  • Chrome

Notre exigence est venue d'un test de sécurité. Après vous être déconnecté de notre site Web, vous pouvez appuyer sur le bouton Retour et afficher les pages mises en cache.


Juste pour ipad Safari, [ceci] [1] aide-t-il? [1]: stackoverflow.com/questions/24524248/…
Bakhshi

Le plus simple est d'utiliser: max-age = 10. Ce n'est pas parfait car la page sera mise en cache pendant 10 secondes. Mais c'est la solution la moins «en-tête spaghetti». En outre, cela améliore parfois considérablement les performances des sites Web dynamiques qui utilisent des proxy inverses. (Votre script PHP lent sera appelé une fois toutes les 10 secondes et sera ensuite mis en cache par le proxy inverse. Une fois toutes les 10 secondes est bien mieux qu'une fois par visiteur)
Hello World


3
Merci pour cette excellente question. Par curiosité, quelle pourrait être la situation qui vous fait envoyer des données sans vouloir que le récepteur les enregistre pour des "raisons de sécurité" . vous les avez déjà envoyés!
Comptable le

1
@Accountant: dans son scénario, l'utilisateur s'était déconnecté. Qui peut garantir que le prochain utilisateur humain sur cet User-Agent sera la personne qui vient de se déconnecter?
Fabien Haddadi

Réponses:


2579

introduction

L'ensemble minimal correct d'en-têtes qui fonctionne sur tous les clients (et proxy) mentionnés:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0

C'est Cache-Controlpar la spécification HTTP 1.1 pour les clients et les proxys (et implicitement requis par certains clients à côté Expires). C'est Pragmaselon la spécification HTTP 1.0 pour les clients préhistoriques. C'est Expiresselon les spécifications HTTP 1.0 et 1.1 pour les clients et les proxys. Dans HTTP 1.1, le Cache-Controlprend le pas sur Expires, donc c'est après tout pour les proxy HTTP 1.0 uniquement.

Si vous ne vous souciez pas d'IE6 et de sa mise en cache cassée lors de la diffusion de pages via HTTPS uniquement no-store, vous pouvez omettre Cache-Control: no-cache.

Cache-Control: no-store, must-revalidate
Pragma: no-cache
Expires: 0

Si vous ne vous souciez pas des clients IE6 ni HTTP 1.0 (HTTP 1.1 a été introduit en 1997), vous pouvez l'omettre Pragma.

Cache-Control: no-store, must-revalidate
Expires: 0

Si vous ne vous souciez pas non plus des proxy HTTP 1.0, vous pouvez les omettre Expires.

Cache-Control: no-store, must-revalidate

D'un autre côté, si le serveur inclut automatiquement un en- Datetête valide , vous pouvez également théoriquement l'omettre Cache-Controlet vous y fier Expiresuniquement.

Date: Wed, 24 Aug 2016 18:32:02 GMT
Expires: 0

Mais cela peut échouer si, par exemple, l'utilisateur final manipule la date du système d'exploitation et que le logiciel client s'y fie.

D'autres Cache-Controlparamètres tels que ne max-agesont pas pertinents si les Cache-Controlparamètres susmentionnés sont spécifiés. L' en- Last-Modifiedtête compris dans la plupart des autres réponses ici est seulement intéressant si vous voulez vraiment mettre en cache la demande, de sorte que vous n'avez pas besoin de préciser tout.

Comment le régler?

Utiliser PHP:

header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.

Utilisation de Java Servlet ou Node.js:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setHeader("Expires", "0"); // Proxies.

Utilisation d'ASP.NET-MVC

Response.Cache.SetCacheability(HttpCacheability.NoCache);  // HTTP 1.1.
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

Utilisation de l'API Web ASP.NET:

// `response` is an instance of System.Net.Http.HttpResponseMessage
response.Headers.CacheControl = new CacheControlHeaderValue
{
    NoCache = true,
    NoStore = true,
    MustRevalidate = true
};
response.Headers.Pragma.ParseAdd("no-cache");
// We can't use `response.Content.Headers.Expires` directly
// since it allows only `DateTimeOffset?` values.
response.Content?.Headers.TryAddWithoutValidation("Expires", 0.ToString()); 

Utilisation d'ASP.NET:

Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.

Utilisation d'ASP.NET Core v3

// using Microsoft.Net.Http.Headers
Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
Response.Headers[HeaderNames.Expires] = "0";
Response.Headers[HeaderNames.Pragma] = "no-cache";

Utilisation d'ASP:

Response.addHeader "Cache-Control", "no-cache, no-store, must-revalidate" ' HTTP 1.1.
Response.addHeader "Pragma", "no-cache" ' HTTP 1.0.
Response.addHeader "Expires", "0" ' Proxies.

Utilisation de Ruby on Rails, ou Python / Flask:

headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
headers["Pragma"] = "no-cache" # HTTP 1.0.
headers["Expires"] = "0" # Proxies.

Utilisation de Python / Django:

response["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response["Pragma"] = "no-cache" # HTTP 1.0.
response["Expires"] = "0" # Proxies.

Utilisation de Python / Pyramid:

request.response.headerlist.extend(
    (
        ('Cache-Control', 'no-cache, no-store, must-revalidate'),
        ('Pragma', 'no-cache'),
        ('Expires', '0')
    )
)

Utilisation de Go:

responseWriter.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") // HTTP 1.1.
responseWriter.Header().Set("Pragma", "no-cache") // HTTP 1.0.
responseWriter.Header().Set("Expires", "0") // Proxies.

Utilisation du .htaccessfichier Apache :

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

En utilisant HTML4:

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">

Méta-balises HTML vs en-têtes de réponse HTTP

Il est important de savoir que lorsqu'une page HTML est servie via une connexion HTTP et qu'un en-tête est présent à la fois dans les en-têtes de réponse HTTP et dans les <meta http-equiv>balises HTML , celui spécifié dans l'en-tête de réponse HTTP aura la priorité sur la balise Meta HTML. La balise Meta HTML ne sera utilisée que lorsque la page est affichée à partir d'un système de fichiers de disque local via une file://URL. Voir aussi le chapitre 5.2.2 de la spécification HTML W3 . Soyez prudent lorsque vous ne les spécifiez pas par programme car le serveur Web peut notamment inclure des valeurs par défaut.

En règle générale, vous feriez mieux de ne pas spécifier les balises META HTML pour éviter toute confusion par les démarreurs et compter sur des en-têtes de réponse HTTP durs. De plus, spécifiquement ces <meta http-equiv>balises ne sont pas valides en HTML5. Seules les http-equivvaleurs répertoriées dans la spécification HTML5 sont autorisées.

Vérification des en-têtes de réponse HTTP réels

Pour vérifier l'un et l'autre, vous pouvez les voir / déboguer dans le moniteur de trafic HTTP du jeu d'outils de développement de webbrowser. Vous pouvez y accéder en appuyant sur F12 dans Chrome / Firefox23 + / IE9 +, puis en ouvrant le panneau à onglets "Réseau" ou "Net", puis en cliquant sur la demande HTTP d'intérêt pour découvrir tous les détails sur la demande et la réponse HTTP. La capture d'écran ci-dessous provient de Chrome:

Moniteur de trafic HTTP du développeur d'outils Chrome montrant les en-têtes de réponse HTTP sur stackoverflow.com

Je souhaite également définir ces en-têtes sur les téléchargements de fichiers

Tout d'abord, cette question et réponse sont ciblées sur les "pages Web" (pages HTML), et non sur les "téléchargements de fichiers" (PDF, zip, Excel, etc.). Vous feriez mieux de les mettre en cache et d'utiliser un identifiant de version de fichier quelque part dans le chemin URI ou la chaîne de requête pour forcer une nouvelle téléchargement sur un fichier modifié. Lorsque vous appliquez ces en-têtes sans cache sur les téléchargements de fichiers, méfiez-vous du bogue IE7 / 8 lors du service de téléchargement de fichiers via HTTPS au lieu de HTTP. Pour plus de détails, voir IE ne peut pas télécharger foo.jsf. IE n'a pas pu ouvrir ce site Internet. Le site demandé est indisponible ou introuvable .


16
Cela ne semble pas être complet. J'ai essayé cette solution sur IE 8 et j'ai constaté que le navigateur chargera une version mise en cache lorsque vous appuyez sur le bouton de retour.
Mike Ottum

16
Votre méthodologie de test était probablement incorrecte. Peut-être que la page était déjà dans le cache? Peut-être que les en-têtes étaient incorrects / remplacés? Peut-être que vous regardiez la mauvaise demande? Etc ..
BalusC

8
En fait, je confirme que cette approche est incomplète et provoque des problèmes avec IE8, ou du moins dans certaines circonstances. Plus précisément, lorsque vous utilisez IE8 pour récupérer une ressource via SSL, IE8 refusera de récupérer la ressource une deuxième fois (soit du tout, soit après un premier essai, selon les en-têtes utilisés). Voir le blog d'EricLaw , par exemple.
haylem

21
Je voudrais ajouter que c'est essentiellement ce que fait Bank of America. Si vous regardez leurs en-têtes de réponse et traduisez cela en aspx, ils font: Response.AppendHeader ("Cache-Control", "no-cache, no-store, must-revalidate"); Response.AppendHeader ("Expires", "Thu, 01 Dec 1994 16:00:00 GMT"); Je pense que si c'est assez bon pour eux, c'est assez bon pour moi.
John

8
@John: cet en-tête expire est exactement la valeur d'exemple dans la spécification HTTP 1.0 . Cela fonctionne, mais c'est un peu ridicule de prendre exactement cet horodatage.
BalusC

244

(Hé, tout le monde: s'il vous plaît, ne copiez et collez pas tous les en-têtes que vous pouvez trouver)

Tout d'abord, l' historique du bouton Retour n'est pas un cache :

Le modèle de fraîcheur (section 4.2) ne s'applique pas nécessairement aux mécanismes d'historique. Autrement dit, un mécanisme d'historique peut afficher une représentation précédente même si elle a expiré.

Dans l'ancienne spécification HTTP, le libellé était encore plus fort, disant explicitement aux navigateurs de ne pas tenir compte des directives de cache pour l'historique du bouton de retour.

Le retour est censé remonter dans le temps (au moment où l'utilisateur était connecté). Il ne navigue pas vers une URL précédemment ouverte.

Cependant, dans la pratique, le cache peut influencer le bouton de retour, dans des circonstances très spécifiques:

  • La page doit être livrée via HTTPS , sinon ce contournement du cache ne sera pas fiable. De plus, si vous n'utilisez pas HTTPS, votre page est vulnérable au vol de connexion de bien d'autres façons.
  • Vous devez envoyer Cache-Control: no-store, must-revalidate(certains navigateurs observent no-storeet certains observent must-revalidate)

Vous n'avez jamais besoin de:

  • <meta>avec des en-têtes de cache - cela ne fonctionne pas du tout. Totalement inutile.
  • post-check/ pre-check- c'est une directive IE uniquement qui ne s'applique qu'aux ressources cachable .
  • Envoi du même en-tête deux ou douze fois. Certains extraits PHP remplacent en fait les en-têtes précédents, ce qui entraîne l'envoi du dernier.

Si vous le souhaitez, vous pouvez ajouter:

  • no-cacheou max-age=0, ce qui rendra la ressource (URL) "périmée" et obligera les navigateurs à vérifier avec le serveur s'il existe une version plus récente ( no-storecela implique déjà cela encore plus fort).
  • Expiresavec une date dans le passé pour les clients HTTP / 1.0 (bien que les vrais clients HTTP / 1.0 uniquement soient totalement inexistants de nos jours).

Bonus: le nouveau RFC de mise en cache HTTP .


1
cela aura-t-il un effet secondaire sur les performances du site en termes de temps de chargement? comment le non-stockage, le non-cache et la revalidation doivent affecter les performances?
Raman Ghai

@RamanGhai La désactivation du cache nuit généralement aux performances (et les 3 options que vous avez mentionnées désactivent la mise en cache). Cela peut rendre les CDN et les proxy ISP (par exemple couramment utilisés par les opérateurs mobiles) inefficaces. Cela ne nuit pas au premier chargement par un nouvel utilisateur (à part le problème de proxy), mais la navigation ultérieure peut être beaucoup plus lente.
Kornel

@porneL vous déclarez que nous devons envoyer Cache-Control: must-revalidate. Pourquoi ne pas envoyer Cache-Control: no-cachecar cela no-cacheimplique déjà must-revalidate? w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
Pacerier

3
@Pacerier la relation no-cacheavec must-revalidateest vraie pour le cache, mais l'historique en arrière n'est pas un cache. Navigateurs spéciaux cas explicites must-revalidatepour contrôler le comportement de l'historique .
Kornel

@porneL, Hmm existe-t-il un RFC de support qui indique que c'est le comportement souhaité?
Pacerier

103

Comme @Kornel l'a déclaré, ce que vous voulez, ce n'est pas de désactiver le cache, mais de désactiver le tampon d'historique. Différents navigateurs ont leurs propres moyens subtils pour désactiver le tampon d'historique.

Dans Chrome (v28.0.1500.95 m), nous ne pouvons le faire que par Cache-Control: no-store.

Dans FireFox (v23.0.1), n'importe lequel de ces éléments fonctionnera:

  1. Cache-Control: no-store

  2. Cache-Control: no-cache (https uniquement)

  3. Pragma: no-cache (https uniquement)

  4. Vary: * (https uniquement)

Dans Opera (v12.15), nous ne pouvons le faire que par Cache-Control: must-revalidate(https uniquement).

Dans Safari (v5.1.7, 7534.57.2), n'importe lequel de ces éléments fonctionnera:

  1. Cache-Control: no-store
    <body onunload=""> en html

  2. Cache-Control: no-store (https uniquement)

Dans IE8 (v8.0.6001.18702IC), n'importe lequel de ces éléments fonctionnera:

  1. Cache-Control: must-revalidate, max-age=0

  2. Cache-Control: no-cache

  3. Cache-Control: no-store

  4. Cache-Control: must-revalidate
    Expires: 0

  5. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT

  6. Pragma: no-cache (https uniquement)

  7. Vary: * (https uniquement)

La combinaison de ce qui précède nous donne cette solution qui fonctionne pour Chrome 28, FireFox 23, IE8, Safari 5.1.7 et Opera 12.15: Cache-Control: no-store, must-revalidate (https uniquement)

Notez que https est nécessaire car Opera ne désactivera pas le tampon d'historique pour les pages http standard. Si vous ne pouvez vraiment pas obtenir https et que vous êtes prêt à ignorer Opera, le mieux que vous puissiez faire est le suivant:

Cache-Control: no-store
<body onunload="">

Ci-dessous montre les journaux bruts de mes tests:

HTTP:

  1. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  2. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  3. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    Échec: Safari 5.1.7, Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8

  4. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Échec: Safari 5.1.7, Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8

  5. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  6. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  7. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  8. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  9. Cache-Control: no-store
    Échec: Safari 5.1.7, Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8

  10. Cache-Control: no-store
    <body onunload="">
    Échec: Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  11. Cache-Control: no-cache
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  12. Vary: *
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Succès: aucun

  13. Pragma: no-cache
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Succès: aucun

  14. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  15. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  16. Cache-Control: must-revalidate, max-age=0
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  17. Cache-Control: must-revalidate
    Expires: 0
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  18. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Échec: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Succès: IE8

  19. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Succès: aucun

HTTPS:

  1. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Succès: aucun

  2. Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Succès: aucun

  3. Vary: *
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  4. Pragma: no-cache
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  5. Cache-Control: no-cache
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  6. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  7. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  8. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  9. Cache-Control: must-revalidate
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Succès: Opera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    Échec: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Succès: Opera 12.15

  11. Cache-Control: must-revalidate, max-age=0
    Échec: Chrome 28, FireFox 23, Safari 5.1.7
    Succès: IE8, Opera 12.15

  12. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, Safari 5.1.7
    Succès: FireFox 23, IE8, Opera 12.15

  13. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Chrome 28, Safari 5.1.7
    Succès: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store
    Échec: Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  15. Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  16. Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Échec: Opera 12.15
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  17. Cache-Control: private, no-cache
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Échec: Chrome 28, Safari 5.1.7, Opera 12.15
    Succès: FireFox 23, IE8

  18. Cache-Control: must-revalidate
    Expires: 0
    Échec: Chrome 28, FireFox 23, Safari 5.1.7,
    Succès: IE8, Opera 12.15

  19. Cache-Control: must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Échec: Chrome 28, FireFox 23, Safari 5.1.7,
    Succès: IE8, Opera 12.15

  20. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7,
    Succès: IE8, Opera 12.15

  21. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    <body onunload="">
    Échec: Chrome 28, FireFox 23, Safari 5.1.7,
    Succès: IE8, Opera 12.15

  22. Cache-Control: private, must-revalidate
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Échec: Chrome 28, Safari 5.1.7
    Succès: FireFox 23, IE8, Opera 12.15

  23. Cache-Control: no-store, must-revalidate
    Échec: aucun
    Succès: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15


3
Je sais que cela a été publié il y a quelques années, mais c'était une lecture intéressante. Ce problème me rend fou depuis quelques mois maintenant, le corps semble vraiment savoir comment gérer le contrôle du cache. J'ai vu quelques personnes utiliser le <body onunload="">mais cela ressemble plus à un moyen de contourner le problème réel. J'ai essayé d'utiliser le .htaccess et de modifier les en-têtes de cette façon, si j'utilise HTTPS, cela devrait-il fonctionner de cette façon? C'est surtout un safari où le problème se pose le plus.
Jordan

4
@Jordan, selon les journaux ci-dessus si vous avez HTTPS, l'ajout Cache-Control: no-storeferait l'affaire. <body onunload="">n'est nécessaire que si vous n'avez pas HTTPS.
Pacerier

37

J'ai trouvé la route web.config utile (j'ai essayé de l'ajouter à la réponse mais ne semble pas avoir été acceptée, alors postez ici)

<configuration>
<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Cache-Control" value="no-cache, no-store, must-revalidate" />
            <!-- HTTP 1.1. -->
            <add name="Pragma" value="no-cache" />
            <!-- HTTP 1.0. -->
            <add name="Expires" value="0" />
            <!-- Proxies. -->
        </customHeaders>
    </httpProtocol>
</system.webServer>

Et voici la manière express / node.js de faire de même:

app.use(function(req, res, next) {
    res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
    res.setHeader('Pragma', 'no-cache');
    res.setHeader('Expires', '0');
    next();
});

Pour web.config, je modifierais juste un peu pour appliquer les en-têtes personnalisés uniquement pour les scripts que nous savons chargés dynamiquement / en utilisant requirejs. En supposant que vos scripts se trouvent dans le dossier client: <location path = "client"> ..... </location>
Ibrahim ben Salah

Pour qui se demande peut-être ce que web.confc'est: il s'agit des principaux paramètres et fichier de configuration d'une ASP.NETapplication Web. Il s'agit d'un document XML qui réside dans le répertoire racine. ( wiki ).
un autre

27

J'ai trouvé que toutes les réponses sur cette page avaient encore des problèmes. En particulier, j'ai remarqué qu'aucun d'entre eux n'empêchait IE8 d'utiliser une version mise en cache de la page lorsque vous y accédiez en appuyant sur le bouton de retour.

Après de nombreuses recherches et tests, j'ai trouvé que les deux seuls en-têtes dont j'avais vraiment besoin étaient:

Cache-Control: no-store
Varie: *

Pour une explication de l'en-tête Vary, consultez http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6

Sur IE6-8, FF1.5-3.5, Chrome 2-3, Safari 4 et Opera 9-10, ces en-têtes ont provoqué la demande de la page au serveur lorsque vous cliquez sur un lien vers la page ou mettez l'URL directement dans la barre d'adresse. Cela couvre environ 99% de tous les navigateurs utilisés en janvier 2010.

Sur IE6 et Opera 9-10, le fait d'appuyer sur le bouton de retour provoquait toujours le chargement de la version mise en cache. Sur tous les autres navigateurs que j'ai testés, ils ont récupéré une nouvelle version sur le serveur. Jusqu'à présent, je n'ai trouvé aucun ensemble d'en-têtes qui empêcherait ces navigateurs de renvoyer les versions mises en cache des pages lorsque vous appuyez sur le bouton Retour.

Mise à jour: Après avoir écrit cette réponse, j'ai réalisé que notre serveur Web s'identifiait comme un serveur HTTP 1.0. Les en-têtes que j'ai énumérés sont les bons pour que les réponses d'un serveur HTTP 1.0 ne soient pas mises en cache par les navigateurs. Pour un serveur HTTP 1.1, regardez la réponse de BalusC .


4
Cela fonctionne pour le bouton de retour d'IE8 !! Après avoir tout essayé dans toutes les autres suggestions, l'ajout de l'en-tête "Vary: *" est apparemment la seule chose qui peut forcer IE8 à recharger la page lorsque l'utilisateur appuie sur le bouton de retour. Et cela fait le travail sur serveurs HTTP / 1.1.
coredumperror

Combiné avec les en-têtes suggérés par BarlusC, plus un extrait JS qui appelle window.location.reload () lorsque l'événement onPageShow se déclenche avec l'attribut "persistant" (nécessaire pour Safari), tous les navigateurs que j'ai testés avec succès forcent un rechargement depuis le serveur lorsque l'utilisateur utilise le bouton Retour.
coredumperror

1
@CoreDumpError, oh vous ne devez pas supposer que JavaScript est activé.
Pacerier

@Pacerier Au moment où j'ai écrit la réponse en 2010, cela fonctionnait sur les dernières versions de Safari et d'Opera, notre serveur s'identifiant comme un serveur HTTP 1.0. Malheureusement, je n'ai plus aucun moyen de tester facilement cela, donc je ne peux rien dire de définitif sur les dernières versions de ces navigateurs.
Chris Vasselli

Avec quelles versions de navigateur avez-vous testé?
Pacerier

21

Après un peu de recherche, nous avons trouvé la liste suivante d'en-têtes qui semblait couvrir la plupart des navigateurs:

Dans ASP.NET, nous les avons ajoutés à l'aide de l'extrait de code suivant:

Response.ClearHeaders(); 
Response.AppendHeader("Cache-Control", "no-cache"); //HTTP 1.1
Response.AppendHeader("Cache-Control", "private"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "no-store"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "must-revalidate"); // HTTP 1.1
Response.AppendHeader("Cache-Control", "max-stale=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "post-check=0"); // HTTP 1.1 
Response.AppendHeader("Cache-Control", "pre-check=0"); // HTTP 1.1 
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0 
Response.AppendHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT"); // HTTP 1.0 

Trouvé sur: http://forums.asp.net/t/1013531.aspx


36
@bart: Encore plus gênant, le 26 juillet 1997 était un samedi, pas un lundi ...
Cᴏʀʏ

5
Cache-Control: no-cacheet Cache-Control: privateaffrontement - vous ne devriez jamais réunir les deux: le premier dit aux navigateurs et aux mandataires de ne pas mettre en cache du tout, le second dit aux mandataires de ne pas mettre en cache, mais permet aux navigateurs de conserver leur propre copie privée. Je ne sais pas quel paramètre le navigateur suivra, mais il est peu probable qu'il soit cohérent entre les navigateurs et les versions.
Keith

N'utilisez pas de pré-contrôle et de post-contrôle. blogs.msdn.com/b/ieinternals/archive/2009/07/20/…
EricLaw

cela n'a pas fonctionné pour moi - en utilisant asp.net 4.5, le code s'exécute mais ne produit pas le résultat requis. J'ai dû suivre ceci: stackoverflow.com/questions/22443932/…
Andy

8

L'utilisation de l'en-tête pragma dans la réponse est un conte d'épouses. RFC2616 le définit uniquement comme un en-tête de demande

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


4
C'est un bon exemple de la raison pour laquelle vous devez aller au-delà des spécifications. Si les spécifications étaient toujours limpides, cela ne servirait à rien pour des sites comme StackOverflow. De Microsoft À des fins de compatibilité descendante avec les serveurs HTTP 1.0, Internet Explorer prend en charge une utilisation spéciale de l'en-tête HTTP Pragma: no-cache. Si le client communique avec le serveur via une connexion sécurisée (https: //) et que le serveur renvoie un en-tête Pragma: no-cache avec la réponse, Internet Explorer ne met pas en cache la réponse.
michaelok

@michaelok: Votre référence est valide, mais manque le point le plus large - Définissez un contrôle de cache / expire approprié et vous n'avez pas besoin de pragma.
EricLaw

8

AVERTISSEMENT: je suggère fortement de lire la réponse de @ BalusC. Après avoir lu le tutoriel de mise en cache suivant: http://www.mnot.net/cache_docs/ (je vous recommande également de le lire), je pense que c'est correct. Cependant, pour des raisons historiques (et parce que je l'ai testé moi-même), je vais inclure ma réponse originale ci-dessous:


J'ai essayé la réponse «acceptée» pour PHP, qui n'a pas fonctionné pour moi. Ensuite, j'ai fait quelques recherches, trouvé une légère variante, l'ai testée et cela a fonctionné. C'est ici:

header('Cache-Control: no-store, private, no-cache, must-revalidate');     // HTTP/1.1
header('Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0', false);  // HTTP/1.1
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT');                  // Date in the past  
header('Expires: 0', false); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header ('Pragma: no-cache');

Cela devrait fonctionner. Le problème était que lors de la définition de la même partie de l'en-tête deux fois, si le falsen'est pas envoyé comme deuxième argument à la fonction d'en-tête, la fonction d'en-tête remplacera simplement l' header()appel précédent . Ainsi, lors de la définition de Cache-Control, par exemple si l'on ne veut pas mettre tous les arguments dans un header()appel de fonction, il doit faire quelque chose comme ceci:

header('Cache-Control: this');
header('Cache-Control: and, this', false);

Voir la documentation plus complète ici .


14
C'est plein de mythes. la pré-vérification et la post-vérification sont uniquement IE, pertinentes uniquement pour les réponses mises en cache, et la valeur 0 est un no-op. max-stale est l'en-tête de demande de proxy, pas l'en-tête de réponse du serveur. Expire n'accepte qu'une seule valeur. Plus d'un entraînera cet en-tête à ignorer.
Kornel

1
@porneL, allez-vous soumettre une réponse concurrente qui traite correctement de ces mythes?
Oddthinking

@Oddthinking, ressemble à stackoverflow.com/questions/49547/… est une réponse concurrente.
Mike Ottum

@Pacerier oui, comme je le dis dans l'avertissement, utilisez la réponse de BalusC.
Steven Oxley

8

Pour ASP.NET Core, créez une classe middleware simple:

public class NoCacheMiddleware
{
    private readonly RequestDelegate m_next;

    public NoCacheMiddleware( RequestDelegate next )
    {
        m_next = next;
    }

    public async Task Invoke( HttpContext httpContext )
    {
        httpContext.Response.OnStarting( ( state ) =>
        {
            // ref: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers
            httpContext.Response.Headers.Append( "Cache-Control", "no-cache, no-store, must-revalidate" );
            httpContext.Response.Headers.Append( "Pragma", "no-cache" );
            httpContext.Response.Headers.Append( "Expires", "0" );
            return Task.FromResult( 0 );
        }, null );

        await m_next.Invoke( httpContext );
    }
}

puis enregistrez-le avec Startup.cs

app.UseMiddleware<NoCacheMiddleware>();

Assurez-vous d'ajouter ceci quelque part après

app.UseStaticFiles();

Je suggérerais d'utiliser des constantes de Microsoft.Net.Http.Headers.HeaderNames au lieu des littéraux de chaîne "Cache-Controls", "Pragma" et "Expires".
Victor Sharovatov

7

Ces directives n'atténuent aucun risque de sécurité. Ils sont vraiment destinés à forcer les UA à actualiser les informations volatiles, pas à empêcher les UA de conserver des informations. Voir cette question similaire . À tout le moins, il n'y a aucune garantie qu'aucun routeur, proxy, etc. n'ignorera également les directives de mise en cache.

Sur une note plus positive, les politiques concernant l'accès physique aux ordinateurs, l'installation de logiciels et autres vous donneront des kilomètres d'avance sur la plupart des entreprises en termes de sécurité. Si les consommateurs de ces informations sont des membres du public, la seule chose que vous pouvez vraiment faire est de les aider à comprendre qu'une fois que les informations atteignent leur machine, cette machine est leur responsabilité, pas la vôtre.


7

Il y a un bug dans IE6

Le contenu avec "Content-Encoding: gzip" est toujours mis en cache même si vous utilisez "Cache-Control: no-cache".

http://support.microsoft.com/kb/321722

Vous pouvez désactiver la compression gzip pour les utilisateurs IE6 (vérifiez l'agent utilisateur pour "MSIE 6")


6

Le RFC pour HTTP 1.1 indique que la bonne méthode consiste à ajouter un en-tête HTTP pour:

Cache-Control: pas de cache

Les navigateurs plus anciens peuvent ignorer cela s'ils ne sont pas correctement conformes à HTTP 1.1. Pour ceux que vous pouvez essayer l'en-tête:

Pragma: pas de cache

Cela est également censé fonctionner pour les navigateurs HTTP 1.1.


1
La spécification indique que la réponse ne doit pas être réutilisée sans revalidation. C'est le Cache-Control: no-store qui est la méthode officielle pour indiquer que la réponse ne sera même pas stockée dans un cache en premier lieu.
AnthonyWJones

6

Définir l'en-tête http modifié à une certaine date en 1995 fait généralement l'affaire.

Voici un exemple:

Expire: Wed, 15 Nov 1995 04:58:08 GMT
Dernière mise à jour: Wed, 15 Nov 1995 04:58:08 GMT
Cache-Control: pas de cache, doit revalider

1
La définition d'une dernière modification il n'y a pas longtemps n'a aucun impact sur la mise en cache, autre que de laisser une réponse mise en cache être utilisée plus longtemps en raison de la revalidation heuristique.
EricLaw

6

La documentation PHP pour la fonction d'en-tête a un exemple assez complet (fourni par un tiers):

    header('Pragma: public');
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");                  // Date in the past   
    header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-store, no-cache, must-revalidate');     // HTTP/1.1
    header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);    // HTTP/1.1
    header ("Pragma: no-cache");
    header("Expires: 0", false);

11
C'est évidemment faux. Les seconds appels à header () pour Expires, Cache-control et Pragma écrasent complètement les valeurs précédemment définies.
Kornel

1
@porneL: Non, ne pas écraser les valeurs précédemment définies car il passe false comme 2e paramètre, indiquant de ne pas remplacer les valeurs précédentes.
Julien Palard

1
@JulienPalard la réponse a été modifiée après avoir fait mon commentaire. Cela n'a toujours pas beaucoup de sens.
Kornel

N'envoyez pas plusieurs en-têtes Cache-Control si vous voulez travailler dans IE avant 9. N'envoyez JAMAIS de pré-vérification ou de post-vérification. blogs.msdn.com/b/ieinternals/archive/2009/07/20/…
EricLaw

6

Si vous rencontrez des problèmes de téléchargement avec IE6-IE8 sur SSL et le cache: pas d'en-tête de cache (et des valeurs similaires) avec les fichiers MS Office, vous pouvez utiliser le cache: privé, pas d'en-tête de magasin et renvoyer le fichier sur demande POST. Ça marche.


6

dans mon cas, je résout le problème en chrome avec ce

<form id="form1" runat="server" autocomplete="off">

où j'ai besoin d'effacer le contenu des données d'un formulaire précédent lorsque les utilisateurs cliquent sur le bouton pour des raisons de sécurité


Mon problème de navigateur mozilla 19.x a également été résolu par l'extrait de code. autocomplete = "off". Je vous remercie.
Satya

5

La réponse acceptée ne semble pas fonctionner pour IIS7 +, en raison du grand nombre de questions sur les en-têtes de cache qui ne sont pas envoyés dans II7:

Etc

La réponse acceptée est correcte dans laquelle les en-têtes doivent être définis, mais pas dans la façon dont ils doivent être définis. Cette méthode fonctionne avec IIS7:

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.AppendCacheExtension("no-store, must-revalidate");
Response.AppendHeader("Pragma", "no-cache");
Response.AppendHeader("Expires", "-1");

La première ligne est définie Cache-controlsur no-cacheet la deuxième ligne ajoute les autres attributsno-store, must-revalidate


Cela fonctionne pour moi:Response.Cache.SetAllowResponseInBrowserHistory(false); Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
Vilx-

4

J'ai obtenu les meilleurs résultats et les plus cohérents sur tous les navigateurs en définissant Pragma: no-cache


4

Les en-têtes de la réponse fournie par BalusC n'empêchent pas Safari 5 (et peut-être les anciennes versions également) d'afficher le contenu du cache du navigateur lors de l'utilisation du bouton de retour du navigateur. Un moyen d'éviter cela consiste à ajouter un attribut de gestionnaire d'événements onunload vide à la balise body:

<body onunload=""> 

Ce piratage brise apparemment le cache arrière dans Safari: y a-t-il un événement de chargement inter-navigateur lorsque vous cliquez sur le bouton Précédent?


Cool, je l'ai testé et cela fonctionne sur Safari (5.1.7) mais pas sur Opera.
Pacerier

4

Aussi, juste pour faire bonne mesure, assurez-vous de réinitialiser le ExpiresDefaultdans votre .htaccessfichier si vous l'utilisez pour activer la mise en cache.

ExpiresDefault "access plus 0 seconds"

Ensuite, vous pouvez utiliser ExpiresByTypepour définir des valeurs spécifiques pour les fichiers que vous souhaitez mettre en cache:

ExpiresByType image/x-icon "access plus 3 month"

Cela peut également être utile si vos fichiers dynamiques, par exemple php, etc. sont mis en cache par le navigateur, et vous ne pouvez pas comprendre pourquoi. Vérifiez ExpiresDefault.


3

En plus des en-têtes, envisagez de diffuser votre page via https . De nombreux navigateurs ne mettent pas en cache https par défaut.


3
//In .net MVC
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult FareListInfo(long id)
{
}

// In .net webform
<%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %>

2

Pour terminer BalusC -> REPONSE Si vous utilisez perl, vous pouvez utiliser CGI pour ajouter des en-têtes HTTP.

Utilisation de Perl:

Use CGI;    
sub set_new_query() {
        binmode STDOUT, ":utf8";
        die if defined $query;
        $query = CGI->new();
        print $query->header(
                        -expires       => 'Sat, 26 Jul 1997 05:00:00 GMT',
                        -Pragma        => 'no-cache',
                        -Cache_Control => join(', ', qw(
                                            private
                                            no-cache
                                            no-store
                                            must-revalidate
                                            max-age=0
                                            pre-check=0
                                            post-check=0 
                                           ))
        );
    }

Utilisation d'apache httpd.conf

<FilesMatch "\.(html|htm|js|css|pl)$">
FileETag None
<ifModule mod_headers.c>
Header unset ETag
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</ifModule>

Remarque: lorsque j'ai essayé d'utiliser le META html, les navigateurs les ont ignorés et ont mis la page en cache.


0

Je veux juste souligner que si quelqu'un veut empêcher la mise en cache UNIQUEMENT du contenu dynamique, l'ajout de ces en-têtes supplémentaires doit être effectué par programme.

J'ai modifié le fichier de configuration de mon projet pour ajouter des en-têtes sans cache, mais cela a également désactivé la mise en cache du contenu statique, ce qui n'est généralement pas souhaitable. La modification des en-têtes de réponse dans le code garantit que les images et les fichiers de style seront mis en cache.

C'est assez évident, mais mérite tout de même d'être mentionné.

Et une autre prudence. Soyez prudent en utilisant la méthode ClearHeaders de la classe HttpResponse. Il peut vous donner quelques ecchymoses si vous l'utilisez de façon imprudente. Comme ça m'a donné.

Après la redirection sur l'événement ActionFilterAttribute, les conséquences de la suppression de tous les en-têtes perdent toutes les données de session et les données du stockage TempData. Il est plus sûr de rediriger à partir d'une action ou de ne pas effacer les en-têtes lors de la redirection.

À la réflexion, je décourage tous d'utiliser la méthode ClearHeaders. Il est préférable de supprimer les en-têtes séparément. Et pour définir correctement l'en-tête Cache-Control, j'utilise ce code:

filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");

0

Je n'ai pas eu de chance avec les <head><meta>éléments. Ajouter des paramètres liés au cache HTTP directement (en dehors du document HTML) fonctionne en effet pour moi.

Un exemple de code en Python utilisant des web.headerappels web.py suit. J'ai délibérément caviardé mon code d'utilité personnel non pertinent.

    importation web
    importer sys
    import PERSONAL-UTILITIES

    myname = "main.py"

    urls = (
        '/', 'main_class'
    )

    main = web.application (urls, globals ())

    render = web.template.render ("templates /", base = "layout", cache = False)

    classe main_class (objet):
        def GET (self):
            web.header ("Cache-control", "no-cache, no-store, must-revalidate")
            web.header ("Pragma", "no-cache")
            web.header ("Expire", "0")
            return render.main_form ()

        DEF POST (auto):
            msg = "PUBLIÉ:"
            form = web.input (fonction = Aucun)
            web.header ("Cache-control", "no-cache, no-store, must-revalidate")
            web.header ("Pragma", "no-cache")
            web.header ("Expire", "0")
            return render.index_laid_out (message d'accueil = msg + formulaire.function)

    si __name__ == "__main__":
        nargs = len (sys.argv)
        # Assurez-vous qu'il y a suffisamment d'arguments après le nom du programme python
        si nargs! = 2:
            LOG-AND-DIE ("% s: erreur de ligne de commande, nargs =% s, devrait être 2", myname, nargs)
        # Assurez-vous que le numéro de port TCP est numérique
        essayer:
            tcp_port = int (sys.argv [1])
        sauf exception comme e:
            LOG-AND-DIE ("% s: tcp_port = int (% s) a échoué (pas un entier)", myname, sys.argv [1])
        # Tout est bien!
        JUST-LOG ("% s: en cours d'exécution sur le port% d", myname, tcp_port)
        web.httpserver.runsimple (main.wsgifunc (), ("localhost", tcp_port))
        main.run ()


N'est-ce pas déjà couvert plusieurs fois dans les réponses qui sont sur le site depuis des années?
Martin Tournoij

Les directives META fonctionnent dans Internet Explorer et les versions d'Edge 18 et antérieures. Les navigateurs modernes ne les prennent pas en charge. crbug.com/2763
EricLaw

0

Voir ce lien vers une étude de cas sur la mise en cache:

http://securityevaluators.com/knowledge/case_studies/caching/

Résumé, selon l'article, ne Cache-Control: no-storefonctionne que sur Chrome, Firefox et IE. IE accepte d'autres contrôles, mais pas Chrome et Firefox. Le lien est une bonne lecture complète avec l'historique de la mise en cache et la documentation de la preuve de concept.


0

Je ne sais pas si ma réponse semble simple et stupide, et elle est peut-être déjà connue depuis longtemps, mais comme empêcher quelqu'un d'utiliser le bouton de retour du navigateur pour afficher vos pages historiques est l'un de vos objectifs, vous pouvez utiliser:

window.location.replace("https://www.example.com/page-not-to-be-viewed-in-browser-history-back-button.html");

Bien sûr, cela peut ne pas être possible à mettre en œuvre sur l'ensemble du site, mais au moins pour certaines pages critiques, vous pouvez le faire. J'espère que cela t'aides.


-1

vous pouvez utiliser le bloc d'emplacement pour définir un fichier individuel au lieu de la mise en cache de l'application entière dans IIS

 <location path="index.html">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Cache-Control" value="no-cache" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.