¿Cómo controlar el almacenamiento en caché de la página web en todos los navegadores?

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 el navegador web almacene en caché determinadas páginas de nuestra aplicación. Esto debe funcionar para al menos los siguientes navegadores:

  • Internet Explorer 6+
  • Firefox 1.5+
  • 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 mencionados (y proxies):

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

El Cache-Control es según la especificación de HTTP 1.1 para clientes y proxies (y 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. El Expires es según las especificaciones HTTP 1.0 y 1.1 para clientes y proxies. En HTTP 1.1, el Cache-Control tiene prioridad sobre Expires , por lo que después de todo solo para los proxies HTTP 1.0.

Si no te importa IE6 y su almacenamiento en caché roto cuando se publican páginas a través de HTTPS con solo no-store , entonces podrías omitir Cache-Control: no-cache .

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

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

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

Si tampoco te importan los proxies HTTP 1.0, entonces podrías omitir Expires .

 Cache-Control: no-store, must-revalidate 

Por otro lado, si el servidor incluye automáticamente un encabezado Date válido, entonces, en teoría, podría omitir también el Cache-Control y depender solamente 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 está confiando en él.

Otros parámetros de Cache-Control , como max-age son irrelevantes si se especifican los parámetros de Cache-Control mencionados anteriormente. El encabezado Last-Modified incluido 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 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()); 

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:

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

Usando 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 Apache .htaccess :

  Header set Cache-Control "no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires 0  

Usando HTML4:

    

Etiquetas meta HTML versus encabezados de respuesta HTTP

Es importante saber que cuando una página HTML se publica a través de una conexión HTTP, y hay un encabezado en los encabezados de respuesta HTTP y HTML , entonces el que se especifica en el encabezado de respuesta HTTP tendrá precedencia sobre la metaetiqueta HTML. La metaetiqueta HTML solo se usará cuando la página se visualice desde el sistema de archivos del disco local a través de un file:// URL. Ver también W3 HTML spec capítulo 5.2.2 . Tenga cuidado con esto cuando no los especifique programáticamente, porque el servidor web puede incluir algunos valores predeterminados.

En general, será mejor que no especifique las metatags HTML para evitar confusiones entre los principiantes y dependa de los encabezados de respuesta HTTP. Además, específicamente esas tags 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 del desarrollador de webbrowser. Puedes acceder presionando F12 en Chrome / Firefox23 + / IE9 +, y luego abriendo el panel de la pestaña “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:

Conjunto de herramientas del desarrollador de Chrome Monitor de tráfico HTTP que muestra los encabezados de respuesta HTTP en stackoverflow.com

Quiero configurar esos encabezados en las 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 guardes en caché y utilices algún identificador de versión de archivo en algún lugar de la ruta URI o querystring para forzar una nueva descarga en un archivo modificado. Al aplicar esos encabezados sin caché en las descargas de archivos de todos modos, tenga cuidado con el error IE7 / 8 cuando se sirve 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: por favor no solo 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 de historial. Es decir, un mecanismo de historial puede mostrar una representación previa incluso si ha expirado.

En la antigua especificación de HTTP, la redacción era aún más sólida, indicando explícitamente a los navegadores que ignorasen las directivas de caché para el historial del botón de retroceso.

Se supone que Back debe retroceder en el tiempo (hasta el momento en que el usuario inició sesión). No avanza hacia una URL abierta previamente.

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

  • La página debe entregarse a través de HTTPS , de lo contrario, esta eliminación de memoria caché no será confiable. Además, si no está usando HTTPS, su página es vulnerable al robo de inicios de sesión de muchas otras maneras.
  • Debe enviar Cache-Control: no-store, must-revalidate (algunos navegadores observan no-store y algunos observan must-revalidate )

Usted nunca necesita ninguno de:

  • con encabezados de caché – no funciona en absoluto. Totalmente inútil.
  • post-check / post-check pre-check : es una directiva solo de IE que solo se aplica a los recursos de caché .
  • Enviando el mismo encabezado dos o doce partes. Algunos fragmentos de PHP realmente reemplazan a los encabezados anteriores, por lo que solo se envía el último.

Si lo desea, puede agregar:

  • no-cache o max-age=0 , lo que hará que el recurso (URL) sea “obsoleto” y requiere que los navegadores comprueben con el servidor si hay una versión más nueva ( no-store ya lo implica aún más).
  • Expires con una fecha anterior para clientes HTTP / 1.0 (aunque los clientes reales HTTP / 1.0 son completamente inexistentes actualmente).

Bonificación: el nuevo HTTP caching RFC .

Como dice porneL, lo que quiere es no desactivar la memoria caché, sino desactivar el búfer de historial. Los diferentes navegadores tienen sus propias formas sutiles de desactivar el búfer de historial.

En Chrome (v28.0.1500.95 m) podemos hacer esto solo con 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: * (https solamente)

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

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

  1. Cache-Control: no-store
    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: * (https solamente)

La combinación de lo anterior nos brinda 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 simples. Si realmente no puede obtener https y está dispuesto a ignorar a Opera, lo mejor que puede hacer es esto:

 Cache-Control: no-store  

A continuación se muestran los registros sin procesar 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: *

    Error: Opera 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: *

    Error: Opera 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: *
    Error: 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: *
    Error: 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: *

    Error: 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: *

    Error: 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: *

    Error: 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: *

    Error: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

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

  10. Cache-Control: no-store

    Error: Opera 12.15
    Éxito: Chrome 28, FireFox 23, IE8, Safari 5.1.7

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

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

  13. Pragma: no-cache
    Error: 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: *

    Error: 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: *

    Error: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Éxito: IE8

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

  17. Cache-Control: must-revalidate
    Expires: 0
    Error: 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
    Error: 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: *

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

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

    Error: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Éxito: ninguno

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

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

  5. Cache-Control: no-cache
    Error: 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
    Error: 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: *
    Error: 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: *
    Error: Chrome 28, Safari 5.1.7, Opera 12.15
    Éxito: FireFox 23, IE8

  9. Cache-Control: must-revalidate
    Error: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Éxito: Opera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0

    Error: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Éxito: Opera 12.15

  11. Cache-Control: must-revalidate, max-age=0
    Error: 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: *

    Error: 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: *

    Error: Chrome 28, Safari 5.1.7
    Éxito: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store
    Error: Opera 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: *

    Error: Opera 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: *

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

  18. Cache-Control: must-revalidate
    Expires: 0
    Error: 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
    Error: 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

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

    Error: 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: *
    Error: 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

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

              

Y aquí está la forma express / 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(); }); 

Descubrí que todas las respuestas en esta página todavía tenían problemas. En particular, noté que ninguno de ellos evitaría que IE8 utilizara una versión en caché de la página cuando accedió al presionar el botón Atrás.

Después de mucha investigación y pruebas, descubrí que los únicos dos encabezados que realmente necesitaba eran:

Cache-Control: sin tienda
Variar: *

Para obtener una explicación del encabezado 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 provocaron 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 de enero de 2010.

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 otros navegadores que probé, buscaron una versión nueva del servidor. Hasta el momento, no he encontrado ningún conjunto de encabezados que provoquen que esos navegadores no devuelvan versiones en caché de las páginas al presionar el botón Atrás.

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

Después de un poco de investigación, se nos ocurrió la siguiente lista de encabezados que parecía abarcar la mayoría de los navegadores:

  • Vence : lunes, 26 de julio de 1997 a las 05:00:00 GMT
  • Cache-Control : no-cache , private, must-revalidate , max-stale = 0, post-check = 0, pre-check = 0 sin tienda
  • Pragma : no-caché

En ASP.NET, agregamos estos 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 uso del encabezado pragma en la respuesta es un cuento de mujeres. RFC2616 solo lo define como un encabezado de solicitud

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

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


Intenté la respuesta ‘aceptada’ para PHP, que no funcionó para mí. Luego hice una pequeña investigación, encontré una pequeña variante, 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 MYH:i:s') . ' GMT'); header ('Pragma: no-cache'); 

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

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

Vea la documentación más completa aquí .

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 desactivar la compresión gzip para usuarios de IE6 (verifique el agente de usuario para “MSIE 6”)

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

Cache-Control: no-caché

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

Pragma: no-caché

Esto también se supone que funciona para los navegadores HTTP 1.1.

Estas directivas no mitigan ningún riesgo de seguridad. En realidad, están destinados a forzar a los AU a actualizar la información volátil, no a evitar que los AU retengan información. Ver esta pregunta similar . Por lo menos, no hay garantía de que ningún enrutador, proxies, etc. tampoco ignore las directivas de caché.

En una nota más positiva, las políticas relacionadas con el acceso físico a las computadoras, la instalación de software y similares le colocarán a millas de distancia de la mayoría de las empresas en términos de seguridad. Si los consumidores de esta información son miembros del público, lo único que 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.

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

Si enfrenta problemas de descarga con IE6-IE8 a través de SSL y caché: encabezado no-caché (y valores similares) con archivos de MS Office, puede usar caché: encabezado privado, sin tienda y devolución de archivo en solicitud POST. Funciona.

en mi caso, soluciono el problema en Chrome con este

 

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

Para ASP.NET Core, crea 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://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 ); } } 

luego regístralo con Startup.cs

 app.UseMiddleware(); 

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

 app.UseStaticFiles(); 

Establecer el encabezado http modificado para una fecha en 1995 suele ser el truco.

Aquí hay un ejemplo:

 Vence: mié, 15 de noviembre de 1995 04:58:08 GMT
 Última modificación: mié, 15 de noviembre de 1995, 04:58:08 GMT
 Cache-Control: no-cache, must-revalidate

Obtuve los mejores y más consistentes resultados en todos los navegadores al configurar Pragma: no-caché

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

  

Aparentemente, este truco rompe el caché de back-forward en Safari: ¿Hay un evento de carga entre navegadores al hacer clic en el botón Atrás?

La respuesta aceptada no parece funcionar para IIS7 +, pasando por la gran cantidad de preguntas sobre los encabezados de caché que no se envían en II7:

  • Algo está obligando a las respuestas a tener control de caché: privado en IIS7
  • IIS7: la configuración de caché no funciona … ¿por qué?
  • Los encabezados de IIS7 + ASP.NET MVC Client Caching no funcionan
  • Establecer el control de caché para páginas aspx
  • Control de caché: sin almacenamiento, debe revalidar no enviado al navegador del cliente en IIS7 + ASP.NET MVC

Y así

La respuesta aceptada es correcta en cuanto a los encabezados que se deben establecer, pero no en cómo se deben establecer. This way works with IIS7:

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

The first line sets Cache-control to no-cache , and the second line adds the other attributes no-store, must-revalidate

In addition to the headers consider serving your page via https . Many browsers will not cache https by default.

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

To complete BalusC -> ANSWER If you are using perl you can use CGI to add HTTP headers.

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

Using apache httpd.conf

  FileETag None  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"  

Note: When I tried to use the html META, browsers ignored them and cached the page.

Also, just for good measure, make sure you reset the ExpiresDefault in your .htaccess file if you’re using that to enable caching.

 ExpiresDefault "access plus 0 seconds" 

Afterwards, you can use ExpiresByType to set specific values for the files you want to cache:

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

This may also come in handy if your dynamic files eg php, etc. are being cached by the browser, and you can’t figure out why. Check ExpiresDefault .

I just want to point out that if someone wants to prevent caching ONLY dynamic content, adding those additional headers should be made programmatically.

I edited configuration file of my project to append no-cache headers, but that also disabled caching static content, which isn’t usually desirable. Modifying response headers in code assures that images and style files will be cached.

This is quite obvious, yet still worth mentioning.

And another caution. Be careful using ClearHeaders method from HttpResponse class. It may give you some bruises if you use it recklessly. Like it gave me.

After redirecting on ActionFilterAttribute event the consequences of clearing all headers are losing all session data and data in TempData storage. It’s safer to redirect from an Action or don’t clear headers when redirection is taking place.

On second thought I discourage all to use ClearHeaders method. It’s better to remove headers separately. And to set Cache-Control header properly I’m using this code:

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

I had no luck with elements. Adding HTTP cache related parameters directly (outside of the HTML doc) does indeed work for me.

Sample code in Python using web.py web.header calls follows. I purposefully redacted my personal irrelevant utility code.


    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)

     si __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
         tratar:
            tcp_port = int(sys.argv[1])
         excepto la Excepción como 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()

See this link to a Case Study on Caching:

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

Summary, according to the article, only Cache-Control: no-store works on Chrome, Firefox and IE. IE accepts other controls, but Chrome and Firefox do not. The link is a good read complete with the history of caching and documenting proof of concept.