Introduction
L'ensemble minimum correct d'en-têtes qui fonctionne sur tous les clients (et proxies) mentionnés :
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
El Cache-Control
est conforme à la spécification HTTP 1.1 pour les clients et les mandataires (et implicitement requis par certains clients à côté de l'option Expires
). Le site Pragma
est conforme à la spécification HTTP 1.0 pour les clients préhistoriques. Le site Expires
est conforme aux spécifications HTTP 1.0 et 1.1 pour les clients et les mandataires. Dans HTTP 1.1, le Cache-Control
a la priorité sur Expires
Il s'agit donc, après tout, de proxies HTTP 1.0 uniquement.
Si vous ne vous préoccupez pas d'IE6 et de sa mise en cache défectueuse lorsque vous servez des pages sur HTTPS avec seulement no-store
alors vous pouvez omettre Cache-Control: no-cache
.
Cache-Control: no-store, must-revalidate
Pragma: no-cache
Expires: 0
Si vous ne vous souciez pas d'IE6 ni des clients HTTP 1.0 (HTTP 1.1 a été introduit en 1997), alors vous pouvez omettre Pragma
.
Cache-Control: no-store, must-revalidate
Expires: 0
Si vous ne vous préoccupez pas non plus des proxies HTTP 1.0, alors vous pouvez omettre Expires
.
Cache-Control: no-store, must-revalidate
D'un autre côté, si le serveur inclut automatiquement un fichier Date
vous pouvez théoriquement omettre l'en-tête Cache-Control
aussi et s'appuyer sur Expires
seulement.
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.
Autre Cache-Control
des paramètres tels que max-age
ne sont pas pertinents si les Cache-Control
sont spécifiés. Le site Last-Modified
L'en-tête, qui figure dans la plupart des autres réponses, est le suivant uniquement intéressant si vous veulent réellement pour mettre la requête en cache, donc vous n'avez pas besoin de le spécifier du tout.
Comment le régler ?
Utilisation de PHP :
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.
En utilisant 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.
Utiliser 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 :
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/Flask :
response = make_response(render_template(...))
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
response.headers["Pragma"] = "no-cache" # HTTP 1.0.
response.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')
)
)
Utiliser 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 de Clojure (require Ring utils) :
(require '[ring.util.response :as r])
(-> response
(r/header "Cache-Control" "no-cache, no-store, must-revalidate")
(r/header "Pragma" "no-cache")
(r/header "Expires" 0))
Utilisation d'Apache .htaccess
fichier :
<IfModule mod_headers.c>
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires 0
</IfModule>
Utilisation de HTML :
<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étabalises HTML et en-têtes de réponse HTTP
Il est important de savoir que lorsqu'une page HTML est servie par une connexion HTTP, et qu'un en-tête est présent dans le fichier les deux les en-têtes de réponse HTTP et le HTML <meta http-equiv>
alors celle spécifiée dans l'en-tête de la réponse HTTP aura la priorité sur la métabalise HTML. La métabalise HTML n'est utilisée que lorsque la page est affichée à partir d'un système de fichiers sur disque local via une balise file://
URL. Voir aussi W3 HTML spec chapitre 5.2.2 . Faites attention lorsque vous ne les spécifiez pas par programme, car le serveur Web peut notamment inclure des valeurs par défaut.
En général, vous feriez mieux de no spécifier les métabalises HTML pour éviter toute confusion de la part des starters et s'appuyer sur les en-têtes de réponse HTTP en dur. De plus, les balises <meta http-equiv>
Les balises sont invalide en HTML5. Seuls les http-equiv
valeurs énumérées dans Spécification HTML5 sont autorisés.
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 de la boîte à outils du développeur du navigateur Web. Vous pouvez y accéder en appuyant sur F12 dans Chrome/Firefox23+/IE9+, puis en ouvrant le panneau de l'onglet "Réseau" ou "Net", et enfin en cliquant sur la requête HTTP qui vous intéresse pour découvrir tous les détails de la requête et de la réponse HTTP. Le site capture d'écran ci-dessous vient de Chrome :
Je veux aussi définir ces en-têtes sur les téléchargements de fichiers.
Tout d'abord, cette question et cette réponse visent les "pages web" (pages HTML), et non 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 un nouveau téléchargement en cas de modification du fichier. Si vous appliquez de toute façon ces en-têtes no-cache aux téléchargements de fichiers, faites attention au bogue d'IE7/8 lorsqu'il s'agit de servir un téléchargement de fichier 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 été en mesure d'ouvrir ce site Internet. Le site demandé est soit indisponible, soit introuvable. .
0 votes
Juste pour l'ipad Safari, est-ce que [ceci][1] aide ? [1] : stackoverflow.com/questions/24524248/
0 votes
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 "spaghetti" qui existe. En outre, cette solution permet parfois d'améliorer considérablement les performances des sites Web dynamiques qui utilisent des proxys inversés. (Votre lent script php sera appelé une fois toutes les 10 secondes et sera ensuite mis en cache par le proxy inverse. Une fois par 10 secondes est bien mieux qu'une fois par visiteur).
4 votes
Voir aussi securityevaluators.com/knowledge/case_studies/caching
5 votes
Merci pour cette excellente question. Par curiosité, quelle est la situation dans laquelle vous envoyez des données sans vouloir que le destinataire les enregistre pour le compte de l'entreprise ? "raisons de sécurité" . vous les avez déjà envoyés !
0 votes
Voir stackoverflow.com/a/49925190/3748498
0 votes
@Accountant, ils sont peut-être préoccupés par les champs de saisie. Le bouton Retour les préserve normalement.
5 votes
@Accountant : dans son scénario, l'utilisateur s'était déconnecté. Qui peut garantir que le prochain utilisateur humain sur cet agent utilisateur sera la personne qui vient de se déconnecter ?