una navegadores navegador los htaccess guardar evitar control caché cache aprovechar aplicación almacenamiento actualizar http caching https http-headers

http - htaccess - ¿Cómo controlar el almacenamiento en caché de páginas web, en todos los navegadores?



no cache html (26)

Nuestras investigaciones nos han demostrado que no todos los navegadores respetan las directivas de caché http de manera uniforme.

Por razones de seguridad, no queremos que ciertas páginas de nuestra aplicación sean almacenadas en caché, nunca, por el navegador web. Esto debe funcionar para al menos los siguientes navegadores:

  • Internet Explorer 6+
  • Firefox 1.5 o superior
  • Safari 3+
  • Opera 9+
  • Cromo

Nuestro requisito vino de una prueba de seguridad. Después de cerrar sesión en nuestro sitio web, puede presionar el botón Atrás y ver las páginas en caché.


Introducción

El conjunto mínimo correcto de encabezados que funciona en todos los clientes (y proxies) mencionados:

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

El Cache-Control es por la especificación de HTTP 1.1 para clientes y proxies (y es implícitamente requerido por algunos clientes al lado de Expires ). El Pragma es según la especificación HTTP 1.0 para clientes prehistóricos. Expires es según la especificación HTTP 1.0 y 1.1 para clientes y proxies. En HTTP 1.1, el Cache-Control tiene prioridad sobre Expires , por lo que es solo para proxies HTTP 1.0.

Si no te importa IE6 y su almacenamiento en caché roto al servir páginas a través de HTTPS solo con no-store , entonces puedes omitir Cache-Control: no-cache .

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

Si no le importan los clientes IE6 ni HTTP 1.0 (HTTP 1.1 se introdujo en 1997), entonces podría omitir Pragma .

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

Si a usted tampoco le importan los proxies HTTP 1.0, puede omitir Expires .

Cache-Control: no-store, must-revalidate

Por otro lado, si el servidor incluye automáticamente un encabezado de Date válido, teóricamente también podrías omitir Cache-Control y depender solo de Expires .

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 parámetros de Cache-Control como max-age son irrelevantes si se especifican los parámetros de Cache-Control antes mencionados. El encabezado Last-Modified que se incluye en la mayoría de las demás respuestas aquí solo es interesante si realmente desea almacenar en caché la solicitud, por lo que no necesita especificarla en absoluto.

¿Cómo configurarlo?

Utilizando PHP:

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

Utilizando 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.

Utilizando 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 la API web de 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());

Utilizando 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.

Utilizando 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:

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.

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'') ) )

Utilizando Google 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 archivo .htaccess 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>

Utilizando 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" />

HTML etiquetas meta vs 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 etiquetas HTML <meta http-equiv> , entonces el que está 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 el sistema de archivos del disco local a través de un file:// URL. Véase también el capítulo 5.2.2 de las especificaciones HTML de W3 . Tenga cuidado con esto cuando no los especifique programáticamente, porque el servidor web puede incluir algunos valores predeterminados.

En general, es mejor que no especifiques las metaetiquetas HTML para evitar confusiones por parte de los principiantes, y confíes en los encabezados de respuesta HTTP difíciles. Además, específicamente esas etiquetas <meta http-equiv> no son válidas en HTML5. Solo se permiten los valores http-equiv listados en la especificación HTML5 .

Verificación de los encabezados de respuesta HTTP reales

Para verificar el uno y el otro, puede verlos / depurarlos en el monitor de tráfico HTTP del conjunto de herramientas para desarrolladores del navegador web. Puede llegar allí 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 captura de pantalla de abajo es de Chrome:

Quiero establecer esos encabezados en descargas de archivos también

En primer lugar, esta pregunta y respuesta está dirigida a "páginas web" (páginas HTML), no a "descargas de archivos" (PDF, zip, Excel, etc.). Será mejor que los guarde en caché y haga uso de algún identificador de versión de archivo en algún lugar de la ruta URI o cadena de consulta para forzar una nueva descarga en un archivo modificado. De todos modos, cuando aplique esos encabezados de no caché en las descargas de archivos, tenga cuidado con el error IE7 / 8 cuando sirva una descarga de archivos a través de HTTPS en lugar de HTTP. Para más detalles, vea 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 .


(hey, todos: no copien y peguen sin pensar todos los encabezados que puedan encontrar)

En primer lugar, el historial del botón Atrás no es un caché :

El modelo de frescura (Sección 4.2) no se aplica necesariamente a los mecanismos históricos. Es decir, un mecanismo de historial puede mostrar una representación previa incluso si ha caducado.

En la antigua especificación de HTTP, la redacción era aún más fuerte, e indicaba explícitamente a los navegadores que ignoraran las directivas de caché para el historial del botón Atrás.

Se supone que Atrás debe retroceder en el tiempo (hasta el momento en que el usuario inició sesión). No navega hacia adelante a una URL abierta previamente.

Sin embargo, en la práctica, el caché puede influir en el botón de retroceso, en circunstancias muy específicas:

  • La página debe entregarse a través de HTTPS , de lo contrario este almacenamiento de caché no será confiable. Además, si no está utilizando HTTPS, su página es vulnerable al robo de acceso de muchas otras formas.
  • Debe enviar Cache-Control: no-store, must-revalidate (algunos navegadores observan no-store y otros must-revalidate )

Nunca necesitas nada de:

  • <meta> con encabezados de caché - no funciona en absoluto. Totalmente inútil.
  • post-check / pre-check : es una directiva solo para IE que solo se aplica a los recursos en caché .
  • Enviando el mismo encabezado dos veces o en docenas de partes. Algunos fragmentos de código PHP por ahí reemplazan los encabezados anteriores, lo que hace que solo se envíe el último.

Si quieres, puedes añadir:

  • no-cache o max-age=0 , lo que hará que el recurso (URL) esté "obsoleto" y requerirá que los navegadores verifiquen con el servidor si hay una versión más nueva ( no-store ya implica que esto es aún más sólido).
  • Expires con una fecha en el pasado para clientes HTTP / 1.0 (aunque en la actualidad los clientes reales solo con HTTP / 1.0 son totalmente inexistentes).

Bonus: El nuevo HTTP de caché RFC .


Como lo indicó porneL, lo que desea es no desactivar el caché, sino desactivar el búfer de historial. Los diferentes navegadores tienen sus propias formas sutiles de deshabilitar el búfer de historial.

En Chrome (v28.0.1500.95 m) solo podemos hacerlo mediante Cache-Control: no-store .

En FireFox (v23.0.1) cualquiera de estos funcionará:

  1. Cache-Control: no-store

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

  3. Pragma: no-cache (solo https)

  4. Vary: * (solo https)

En Opera (v12.15) solo podemos hacer esto mediante Cache-Control: must-revalidate (solo https).

En Safari (v5.1.7, 7534.57.2) cualquiera de estos funcionará:

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

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

En IE8 (v8.0.6001.18702IC) cualquiera de estos funcionará:

  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 (solo https)

  7. Vary: * (solo https)

La combinación de lo anterior nos da esta solución que funciona para Chrome 28, FireFox 23, IE8, Safari 5.1.7 y Opera 12.15: Cache-Control: no-store, must-revalidate (solo https)

Tenga en cuenta que https es necesario porque Opera no desactivará el búfer de historial para páginas http sin formato. Si realmente no puede obtener https y está preparado para ignorar Opera, lo mejor que puede hacer es esto:

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

A continuación se muestran los registros en bruto de mis pruebas:

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="">
    Falla: la ópera 12.15
    Éxito: 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="">
    Falla: la ópera 12.15
    Éxito: 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: *
    Falla: Safari 5.1.7, Opera 12.15
    Éxito: 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: *
    Falla: Safari 5.1.7, Opera 12.15
    Éxito: 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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: 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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: 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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: 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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

  9. Cache-Control: no-store
    Falla: Safari 5.1.7, Opera 12.15
    Éxito: Chrome 28, FireFox 23, IE8

  10. Cache-Control: no-store
    <body onunload="">
    Falla: la ópera 12.15
    Éxito: Chrome 28, FireFox 23, IE8, Safari 5.1.7

  11. Cache-Control: no-cache
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

  12. Vary: *
    Falla: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Éxito: ninguno

  13. Pragma: no-cache
    Falla: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Éxito: ninguno

  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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: 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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

  16. Cache-Control: must-revalidate, max-age=0
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

  17. Cache-Control: must-revalidate
    Expires: 0
    Falla: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

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

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

HTTPS:

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

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

  3. Vary: *
    Falla: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: FireFox 23, IE8

  4. Pragma: no-cache
    Falla: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: FireFox 23, IE8

  5. Cache-Control: no-cache
    Falla: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: FireFox 23, IE8

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

  7. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    Falla: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: 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: *
    Falla: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: FireFox 23, IE8

  9. Cache-Control: must-revalidate
    Falla: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Éxito: la ópera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    Falla: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Éxito: la ópera 12.15

  11. Cache-Control: must-revalidate, max-age=0
    Falla: Chrome 28, FireFox 23, Safari 5.1.7
    Éxito: 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="">
    Falla: Chrome 28, Safari 5.1.7
    Éxito: 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="">
    Falla: Chrome 28, Safari 5.1.7
    Éxito: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store
    Falla: la ópera 12.15
    Éxito: 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="">
    Falla: la ópera 12.15
    Éxito: 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="">
    Falla: la ópera 12.15
    Éxito: 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: *
    Falla: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: FireFox 23, IE8

  18. Cache-Control: must-revalidate
    Expires: 0
    Falla: Chrome 28, FireFox 23, Safari 5.1.7,
    Éxito: IE8, Opera 12.15

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

  20. Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    <body onunload="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7,
    Éxito: 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="">
    Falla: Chrome 28, FireFox 23, Safari 5.1.7,
    Éxito: IE8, Opera 12.15

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

  23. Cache-Control: no-store, must-revalidate
    Fallo: ninguno
    Éxito: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15


DESCARGO DE RESPONSABILIDAD: Sugiero encarecidamente leer la respuesta de @BalusC Después de leer el siguiente tutorial de almacenamiento en caché: http://www.mnot.net/cache_docs/ (También te recomiendo que lo leas), creo que es correcto. Sin embargo, por razones históricas (y porque lo he probado yo mismo), incluiré mi respuesta original a continuación:

Probé la respuesta ''aceptada'' para PHP, que no funcionó para mí. Luego hice una pequeña investigación, encontré una variante ligera, la probé y funcionó. Aquí está:

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'');

Eso debería funcionar. El problema fue que cuando se configura la misma parte del encabezado dos veces, si el false no se envía como segundo argumento a la función de encabezado, la función de encabezado simplemente sobrescribirá la llamada del header() anterior. Entonces, al configurar el Cache-Control , por ejemplo, si uno no quiere poner todos los argumentos en una llamada de función de header() , debe hacer algo como esto:

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

Ver más documentación completa here .


Después de un poco de investigación, encontramos la siguiente lista de encabezados que parecían cubrir la mayoría de los navegadores:

En ASP.NET los agregamos usando el siguiente fragmento de código:

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

Encontrado en: http://forums.asp.net/t/1013531.aspx


El RFC para HTTP 1.1 dice que el método correcto es agregar un encabezado HTTP para:

Control de caché: no-caché

Los navegadores más antiguos pueden ignorar esto si no cumplen correctamente con HTTP 1.1. Para aquellos puedes probar el encabezado:

Pragma: no-caché

También se supone que esto funciona para los navegadores HTTP 1.1.



Encontré la ruta web.config útil (intenté agregarla a la respuesta pero no parece haber sido aceptada, así que publique aquí)

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

Y aquí está la forma expresa / node.js de hacer lo mismo:

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(); });


Encontré que todas las respuestas en esta página todavía tenían problemas. En particular, noté que ninguno de ellos detendría a IE8 de usar una versión en caché de la página cuando accedas a ella presionando el botón Atrás.

Después de mucha investigación y pruebas, descubrí que las dos únicas cabeceras que realmente necesitaba eran:

Cache-Control: no-store
Variar: *

Para obtener una explicación del encabezado de Vary, consulte http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6

En IE6-8, FF1.5-3.5, Chrome 2-3, Safari 4 y Opera 9-10, estos encabezados hicieron que la página se solicitara desde el servidor al hacer clic en un enlace a la página, o poner la URL directamente en la barra de direcciones. Eso cubre aproximadamente el 99% de todos los navegadores en uso a partir del 10 de enero.

En IE6, y Opera 9-10, al presionar el botón Atrás todavía se cargaba la versión en caché. En todos los demás navegadores que probé, obtuvieron una versión nueva del servidor. Hasta ahora, no he encontrado ningún conjunto de encabezados que haga que esos navegadores no devuelvan versiones de páginas en caché cuando presionas el botón Atrás.

Actualización: Después de escribir esta respuesta, me di cuenta de que nuestro servidor web se está identificando como un servidor HTTP 1.0. Los encabezados que he enumerado son los correctos para que las respuestas de un servidor HTTP 1.0 no sean almacenadas en caché por los navegadores. Para un servidor HTTP 1.1, mira la answer de BalusC.


Establecer el encabezado http modificado en alguna fecha en 1995 generalmente funciona.

Aquí hay un ejemplo:

Expires: Wed, 15 Nov 1995 04:58:08 GMT Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT Cache-Control: no-cache, must-revalidate


Estas directivas no mitigan ningún riesgo de seguridad. Realmente tienen la intención de obligar a los UA a actualizar la información volátil, no a evitar que los UA retengan información. Vea esta pregunta similar . Como mínimo, no hay garantía de que ningún enrutador, proxy, etc. no ignorará las directivas de almacenamiento en caché también.

En una nota más positiva, las políticas con respecto al acceso físico a las computadoras, la instalación de software y similares le pondrán a la vanguardia en términos de seguridad. Si los consumidores de esta información son miembros del público, lo único que realmente puede hacer es ayudarlos a comprender que una vez que la información llega a su máquina, esa máquina es su responsabilidad, no la suya.


Hay un error en IE6

El contenido con "Content-Encoding: gzip" siempre se almacena en caché incluso si usa "Cache-Control: no-cache".

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

Puede deshabilitar la compresión gzip para los usuarios de IE6 (consulte el agente de usuario para "MSIE 6")


He obtenido mejores y más consistentes resultados en todos los navegadores al configurar Pragma: no-cache


La documentación de PHP para la función de encabezado tiene un ejemplo bastante completo (contribuido por un tercero):

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);


La respuesta aceptada no parece funcionar para IIS7 +, debido a la gran cantidad de preguntas sobre los encabezados de caché que no se enviaron en II7:

  • Algo está forzando que las respuestas tengan control de caché: privado en IIS7
  • IIS7: configuración de caché no funciona ... ¿por qué?
  • Los encabezados de almacenamiento en caché del cliente MVC de IIS7 + ASP.NET no funcionan
  • Establecer el control de caché para las páginas aspx
  • Control de caché: no-store, must-revalidate no enviado al navegador del cliente en IIS7 + ASP.NET MVC

Y así

La respuesta aceptada es correcta en qué encabezados se deben establecer, pero no en cómo se deben establecer. De esta manera funciona con IIS7:

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

La primera línea se establece Cache-controlen no-cache, y la segunda línea agrega los otros atributosno-store, must-revalidate


Los encabezados en la respuesta proporcionada por BalusC no impiden que Safari 5 (y posiblemente también las versiones más antiguas) muestren contenido desde la memoria caché del navegador cuando se usa el botón de retroceso del navegador. Una forma de evitar esto es agregar un atributo de controlador de eventos onunload vacío a la etiqueta del cuerpo:

<body onunload="">

Este truco aparentemente rompe el caché de avance en Safari: ¿hay un evento de carga de navegador cruzado al hacer clic en el botón Atrás?


Para ASP.NET Core, cree una clase de 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://.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 ); } }

luego registralo con Startup.cs

app.UseMiddleware<NoCacheMiddleware>();

Asegúrate de agregar esto en algún lugar después de

app.UseStaticFiles();


Si tiene problemas de descarga con IE6-IE8 sobre SSL y caché: encabezado sin caché (y valores similares) con archivos de MS Office, puede usar caché: privado, encabezado sin almacén y archivo de retorno en la solicitud POST. Funciona.


en mi caso soluciono el problema en chrome con esto

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

donde necesito borrar el contenido de los datos de un formulario anterior cuando los usuarios hacen clic en el botón de nuevo por razones de seguridad


Solo quiero señalar que si alguien quiere evitar el almacenamiento en caché SOLAMENTE de contenido dinámico, agregar esos encabezados adicionales debe hacerse mediante programación.

Edité el archivo de configuración de mi proyecto para agregar encabezados sin caché, pero eso también deshabilitó el almacenamiento en caché de contenido estático, lo que no suele ser deseable. La modificación de los encabezados de respuesta en el código garantiza que las imágenes y los archivos de estilo se almacenarán en caché.

Esto es bastante obvio, pero vale la pena mencionar.

Y otra precaución. Tenga cuidado al usar el método ClearHeaders de la clase HttpResponse. Puede darle algunos moretones si lo usa imprudentemente. Al igual que me dio.

Después de redirigir en el evento ActionFilterAttribute, las consecuencias de borrar todos los encabezados están perdiendo todos los datos de la sesión y los datos en el almacenamiento TempData. Es más seguro redirigir desde una Acción o no borrar los encabezados cuando se lleva a cabo la redirección.

Pensándolo bien, desaliento a todos a usar el método ClearHeaders. Es mejor eliminar los encabezados por separado. Y para configurar correctamente el encabezado de Cache-Control, estoy usando este código:

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


Vea este enlace a un estudio de caso sobre almacenamiento en caché:

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

Resumen, según el artículo, solo Cache-Control: no-storefunciona en Chrome, Firefox e IE. IE acepta otros controles, pero Chrome y Firefox no. El enlace es una buena lectura completa con el historial de almacenamiento en caché y documentación de prueba de concepto.


Además de los encabezados, considera servir tu página a través de https . Muchos navegadores no almacenan en caché https por defecto.


Además, solo para una buena medida, asegúrese de restablecer el archivo ExpiresDefaulten su .htaccessarchivo si lo está utilizando para habilitar el almacenamiento en caché.

ExpiresDefault "access plus 0 seconds"

Después, puede utilizar ExpiresByTypepara establecer valores específicos para los archivos que desea almacenar en caché:

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

Esto también puede ser útil si el navegador almacena sus archivos dinámicos, por ejemplo, php, etc., y no puede entender por qué. Compruebe ExpiresDefault.


No tuve suerte con los <head><meta>elementos. Agregar parámetros relacionados con la memoria caché HTTP directamente (fuera del documento HTML) realmente funciona para mí.

A continuación se muestra un código de muestra en Python que utiliza web.headerllamadas web.py. Redacté a propósito mi código de utilidad irrelevante personal.

import web import sys import PERSONAL-UTILITIES myname = "main.py" urls = ( ''/'', ''main_class'' ) main = web.application(urls, globals()) render = web.template.render("templates/", base="layout", cache=False) class main_class(object): def GET(self): web.header("Cache-control","no-cache, no-store, must-revalidate") web.header("Pragma", "no-cache") web.header("Expires", "0") return render.main_form() def POST(self): msg = "POSTed:" form = web.input(function = None) web.header("Cache-control","no-cache, no-store, must-revalidate") web.header("Pragma", "no-cache") web.header("Expires", "0") return render.index_laid_out(greeting = msg + form.function) if __name__ == "__main__": nargs = len(sys.argv) # Ensure that there are enough arguments after python program name if nargs != 2: LOG-AND-DIE("%s: Command line error, nargs=%s, should be 2", myname, nargs) # Make sure that the TCP port number is numeric try: tcp_port = int(sys.argv[1]) except Exception as e: LOG-AND-DIE ("%s: tcp_port = int(%s) failed (not an integer)", myname, sys.argv[1]) # All is well! JUST-LOG("%s: Running on port %d", myname, tcp_port) web.httpserver.runsimple(main.wsgifunc(), ("localhost", tcp_port)) main.run()


Para completar BalusC -> answer Si está utilizando perl, puede usar CGI para agregar encabezados HTTP.

Utilizando 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 )) ); }

Utilizando 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>

Nota: cuando intenté usar el META html, los navegadores los ignoraron y guardaron la página en caché.


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