Introducción
El conjunto mínimo correcto de encabezados que funciona en todos los clientes mencionados (y servidores proxy):
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
El Cache-Control
es por la especificación HTTP 1.1 para clientes y proxies (y es requerido implícitamente por algunos clientes al lado Expires
) El Pragma
es por la especificación HTTP 1.0 para clientes prehistóricos. El Expires
es según las especificaciones HTTP 1.0 y 1.1 para clientes y proxies. En HTTP 1.1, Cache-Control
prevalece sobre Expires
, por lo que es, después de todo, solo para proxies HTTP 1.0.
Si no le importa IE6 y su almacenamiento en caché roto cuando solo sirve páginas a través de HTTPS no-store
, puede omitirlo Cache-Control: no-cache
.
Cache-Control: no-store, must-revalidate
Pragma: no-cache
Expires: 0
Si no le interesan los clientes IE6 ni HTTP 1.0 (HTTP 1.1 se introdujo en 1997), puede omitirlo Pragma
.
Cache-Control: no-store, must-revalidate
Expires: 0
Si tampoco te interesan los proxys HTTP 1.0, entonces puedes omitirlos Expires
.
Cache-Control: no-store, must-revalidate
Por otro lado, si el servidor incluye automáticamente un Date
encabezado válido , teóricamente Cache-Control
también podría omitirlo y confiar Expires
solo en él.
Date: Wed, 24 Aug 2016 18:32:02 GMT
Expires: 0
Pero eso puede fallar si, por ejemplo, el usuario final manipula la fecha del sistema operativo y el software del cliente depende de ella.
Otros Cache-Control
parámetros como max-age
son irrelevantes si Cache-Control
se especifican los parámetros mencionados anteriormente . El Last-Modified
encabezado como se incluye en la mayoría de las otras respuestas aquí solo es interesante si realmente desea almacenar en caché la solicitud, por lo que no necesita especificarla en absoluto.
¿Cómo configurarlo?
Usando PHP:
header("Cache-Control: no-cache, no-store, must-revalidate"); // HTTP 1.1.
header("Pragma: no-cache"); // HTTP 1.0.
header("Expires: 0"); // Proxies.
Usando Java Servlet, o 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.
Usando 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.
Usando ASP.NET Web API:
// `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());
Usando 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.
Usando 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";
Usando 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.
Usando Ruby on Rails, o 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.
Usando 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.
Usando Python / Pyramid:
request.response.headerlist.extend(
(
('Cache-Control', 'no-cache, no-store, must-revalidate'),
('Pragma', 'no-cache'),
('Expires', '0')
)
)
Usando 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.
Usando el .htaccess
archivo 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>
Usando 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">
Metaetiquetas HTML frente a encabezados de respuesta HTTP
Es importante saber que cuando se sirve una página HTML a través de una conexión HTTP, y un encabezado está presente tanto en los encabezados de respuesta HTTP como en las <meta http-equiv>
etiquetas HTML , entonces el especificado en el encabezado de respuesta HTTP tendrá prioridad sobre la metaetiqueta HTML. La metaetiqueta HTML solo se utilizará cuando la página se vea desde un sistema de archivos de disco local a través de una file://
URL. Ver también W3 HTML spec capítulo 5.2.2 . Tenga cuidado con esto cuando no los especifique mediante programación porque el servidor web puede incluir algunos valores predeterminados.
En general, es mejor que no especifique las metaetiquetas HTML para evitar confusiones por parte de los principiantes y confiar en los encabezados de respuesta HTTP. Además, específicamente esas <meta http-equiv>
etiquetas no son válidas en HTML5. Solo se permiten los http-equiv
valores enumerados en la especificación HTML5 .
Verificación de los encabezados de respuesta HTTP reales
Para verificar uno y otro, puede verlos / depurarlos en el monitor de tráfico HTTP del conjunto de herramientas de desarrollo del navegador web. Puede llegar presionando F12 en Chrome / Firefox23 + / IE9 + y luego abriendo el panel de pestañas "Red" o "Red", y luego haciendo clic en la solicitud HTTP de interés para descubrir todos los detalles sobre la solicitud y respuesta HTTP. La siguiente captura de pantalla es de Chrome:
También quiero configurar esos encabezados en las descargas de archivos
En primer lugar, esta pregunta y respuesta están dirigidas a "páginas web" (páginas HTML), no a "descargas de archivos" (PDF, zip, Excel, etc.). Será mejor que los guarde en caché y utilice algún identificador de versión de archivo en algún lugar de la ruta URI o cadena de consulta para forzar una descarga en un archivo modificado. Cuando aplique esos encabezados sin caché en las descargas de archivos de todos modos, tenga cuidado con el error IE7 / 8 al realizar una descarga de archivos a través de HTTPS en lugar de HTTP. Para más detalles, consulte IE no puede descargar foo.jsf. IE no pudo abrir este sitio de Internet. El sitio solicitado no está disponible o no se puede encontrar .