¿Cómo controlar el almacenamiento en caché de páginas 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 ciertas páginas de nuestra aplicación se almacenen en caché, nunca, por el navegador web. Esto debe funcionar para al menos los siguientes navegadores:

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

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

Author: Ivaylo Strandjev, 2008-09-08

26 answers

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 HTTP 1.1 para clientes y proxies (e implícitamente requerido por algunos clientes junto a Expires). Las Pragma es por la especificación HTTP 1.0 para clientes prehistóricos. Las 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 es después todo solo para proxies HTTP 1.0.

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

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

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

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

Si tampoco le importan los proxies HTTP 1.0, entonces podría omitir Expires.

Cache-Control: no-store, must-revalidate

Por otro lado, si el servidor incluye automáticamente un encabezado Date válido, entonces usted teóricamente podría omitir Cache-Control también y confiar en Expires solamente.

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 cliente confía en ella.

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

Utilizando ASP.NET API web:

// `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.

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:{[42]]}

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:{[42]]}

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: {[42]]}

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

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

Etiquetas meta HTML vs encabezados de respuesta HTTP

Es importante saber que cuando una página HTML se sirve a través de una conexión HTTP, y un encabezado está presente en tanto los encabezados de respuesta HTTP como las etiquetas HTML <meta http-equiv>, entonces el especificado en el encabezado de respuesta HTTP tendrá prioridad sobre la etiqueta meta HTML. La meta etiqueta HTML solo se utilizará cuando la página se visualice desde el sistema de archivos de disco local a través de una URL file://. Véase 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, es mejor que solo no especifique las meta etiquetas HTML para evitar confusiones por los principiantes, y confíe en encabezados de respuesta HTTP duros. Además, específicamente esas etiquetas <meta http-equiv> son inválido en HTML5. Solo los valores http-equiv enumerados en la especificación HTML5 son permitir.

Verificando los encabezados de respuesta HTTP reales

Para verificar el uno y el otro, puede ver/depurar en el monitor de tráfico HTTP del conjunto de herramientas para desarrolladores de webbrowser. Puede llegar allí 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 HTTP y la respuesta. La siguiente captura de pantalla es de Chrome:

Chrome developer toolset HTTP traffic monitor mostrando encabezados de respuesta HTTP en stackoverflow.com

Quiero para establecer 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.). Es mejor tenerlos en caché y hacer uso de algún identificador de versión de archivo en algún lugar de la ruta de URI o querystring para forzar una nueva descarga en un archivo cambiado. Al aplicar esos encabezados sin caché en las descargas de archivos de todos modos, tenga cuidado con el error IE7/8 al servir una descarga de archivos a través de HTTPS en lugar de HTTP. Para más detalles, véase 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.

 2180
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-27 16:13:48

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

En primer lugar, El historial del botón atrás no es una 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 anterior incluso si ha expirado.

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

Back se supone que retrocede en el tiempo (al momento en que el usuario estaba conectado). No navega hacia adelante a una URL previamente abierta.

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

  • Page debeser entregada a través de HTTPS, de lo contrario este cache-busting no será confiable. Además, si no estás usando HTTPS, entonces tu página es vulnerable a login robando 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 cualquiera de:

  • <meta> con encabezados de caché - no funciona en absoluto. Totalmente inútil.
  • post-check/pre-check - es la directiva IE-only que solo se aplica a los recursos cachable.
  • Enviando el mismo encabezado dos veces o en docenas de partes. Algunos fragmentos de PHP por ahí realmente reemplazan encabezados anteriores, lo que resulta en sólo el último está siendo enviado.

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 comprueben con el servidor si hay una versión más nueva (no-store ya implica esto aún más fuerte).
  • Expires con una fecha en el pasado para los clientes HTTP/1.0 (aunque los clientes reales solo HTTP/1.0 son completamente inexistentes en estos días).

Bonus: El nuevo caché HTTP RFC.

 209
Author: Kornel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-19 12:24:36

Como dijo porneL, lo que desea no es desactivar la 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) podemos hacer esto solo por 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 (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. 18702 IC) cualquiera de estos trabajo:

  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 (https únicamente)

Tenga en cuenta que se necesita https porque Opera no desactivaría el búfer de historial para páginas http simples. Si realmente no puedes obtener https y estás preparado para ignorar Opera, lo mejor que puedes hacer es esto:

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

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: *
    <body onunload="">
    Fail: 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: *
    <body onunload="">
    Fail: 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: Cromo 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: Cromo 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="">
    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: *
    <body onunload="">
    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: *
    <body onunload="">
    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: *
    <body onunload="">
    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
    <body onunload="">
    Fail: 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: *
    <body onunload="">
    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: *
    <body onunload="">
    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: *
    <body onunload="">
    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
    <body onunload="">
    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
    <body onunload="">
    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: Ópera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    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: *
    <body onunload="">
    Error: Cromo 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="">
    Error: Cromo 28, Safari 5.1.7
    Éxito: FireFox 23, IE8, Opera 12.15

  14. Cache-Control: no-store
    Fail: 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: *
    <body onunload="">
    Fail: 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: *
    <body onunload="">
    Fail: 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
    <body onunload="">
    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
    <body onunload="">
    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: Cromo 28, Safari 5.1.7
    Éxito: FireFox 23, IE8, Opera 12.15

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

 84
Author: Pacerier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-29 16:50:36

Encontré la web.ruta de configuración útil (trató de añadirlo a la respuesta, pero no parece haber sido aceptado por lo que la publicación 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á el nodo express/.js manera 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();
});
 25
Author: Joseph Connolly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-23 12:21:46

Encontré que todas las respuestas en esta página todavía tenían problemas. En particular, me di cuenta de que ninguno de ellos detendría IE8 de usar una versión en caché de la página cuando se accede pulsando 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: no-store
Vary: *

Para una explicación del encabezado Vary, echa un vistazo 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 causaron que la página se solicitara al servidor cuando hace clic en un enlace a la página, o coloca la URL directamente en la barra de direcciones. Que cubre alrededor 99% de todos los navegadores en uso a partir de enero ' 10.

En IE6, y Opera 9-10, presionar el botón atrás todavía causaba que la versión en caché se cargara. En todos los demás navegadores I probado, ellos obtuvieron una versión nueva del servidor. Hasta ahora, no he encontrado ningún conjunto de encabezados que causen que esos navegadores no devuelvan las versiones en caché de las páginas cuando presione el botón atrás.

Update: 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 los navegadores no almacenen en caché las respuestas de un servidor HTTP 1.0. Para un servidor HTTP 1.1, mire La respuesta de BalusC .

 23
Author: Chris Vasselli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:39

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

En ASP.NET hemos añadido estos usando el siguiente fragmento:

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 desde: http://forums.asp.net/t/1013531.aspx

 18
Author: Edward Wilde,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 13:55:28

El uso de la cabecera pragma en la respuesta es un cuento de esposas. RFC2616 solo lo define como un encabezado de solicitud

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

 8
Author: Dave Cheney,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-17 14:18:00

DESCARGO DE RESPONSABILIDAD: Recomiendo encarecidamente 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:


Probé la respuesta 'aceptada' para PHP, que no funcionó para mí. Luego investigué un poco, encontré una pequeña variante, la probé y funcionó. Aqui es:

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 era que al configurar 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 anterior header(). Por lo tanto, al establecer el 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);

Ver documentación más completa aquí.

 7
Author: Steven Oxley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-25 16:15:29

Hay un error en IE6

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

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

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

 7
Author: Edson Medina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-01 10:20:47

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

Cache-Control: no-cache

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

Pragma: no-cache

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

 6
Author: Chris Dail,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-08 12:14:57

Estas directivas no mitigan ningún riesgo de seguridad. Realmente están destinados a forzar a los UA a actualizar la información volátil, no a evitar que los UA retengan información. Ver esta pregunta similar. Por lo menos, 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 lo pondrán a millas por delante 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 realmente puede hacer es ayudarlos a entender que una vez que la información llega a su máquina, esa máquina es su responsabilidad, no suya.

 6
Author: Dustman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:57

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);
 6
Author: Grey Panther,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-13 18:27:44

Si se enfrenta a 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 tienda y archivo de retorno en la solicitud POSTERIOR. Funciona.

 6
Author: Albert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-21 09:02:33

En mi caso soluciono el problema en chrome con este

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

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

 6
Author: user2321638,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-19 17:28:58

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://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<NoCacheMiddleware>();

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

app.UseStaticFiles();
 6
Author: kspearrin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-19 20:09:11

Establecer el encabezado http modificado en alguna fecha en 1995 generalmente hace el truco.

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
 5
Author: Anders Sandvig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-19 08:23:21

He tenido los mejores y más consistentes resultados en todos los navegadores configurando Pragma: no-cache

 4
Author: petr k.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-17 12:32:53

Los encabezados de la respuesta proporcionada por BalusC no impiden que Safari 5 (y posiblemente versiones anteriores también) muestre contenido de la caché del navegador cuando se utiliza el botón atrás del navegador. Una forma de evitar esto es agregar un atributo onunload event handler vacío a la etiqueta body:

<body onunload=""> 

Este hack aparentemente rompe la caché de retroceso en Safari: ¿Hay un evento de carga cruzada del navegador al hacer clic en el botón atrás?

 4
Author: Tobias,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:39

La respuesta aceptada no parece funcionar para IIS7+, teniendo en cuenta el gran número de preguntas sobre los encabezados de caché que no se envían en II7:

Y así sucesivamente

La respuesta aceptada es correcta en qué encabezados se deben establecer, pero no en cómo se deben establecer. 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 establece Cache-control a no-cache, y la segunda línea agrega los otros atributos no-store, must-revalidate

 4
Author: JK.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:45

También, solo para una buena medida, asegúrese de restablecer el ExpiresDefault en su archivo .htaccess si lo está utilizando para habilitar el almacenamiento en caché.

ExpiresDefault "access plus 0 seconds"

Después, puede usar ExpiresByType para 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 sus archivos dinámicos, por ejemplo, php, etc. están siendo almacenados en caché por el navegador, y no se puede averiguar por qué. Compruebe ExpiresDefault.

 4
Author: Obinwanne Hill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-19 20:47:34

Además de los encabezados, considere servir su página a través de https. Muchos navegadores no almacenarán https en caché de forma predeterminada.

 3
Author: Harry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-19 08:31:33
//In .net MVC
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult FareListInfo(long id)
{
}

// In .net webform
<%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %>
 3
Author: yongfa365,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-06 08:52:53

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

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

Usando 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 almacenaron la página en caché.

 3
Author: Carlos Escalera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32

Solo quiero señalar que si alguien quiere evitar almacenar en caché SOLO contenido dinámico, la adición de esas cabeceras 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 generalmente no es deseable. La modificación de los encabezados de respuesta en el código asegura que las imágenes y los archivos de estilo se almacenarán en caché.

Esto es bastante obvio, pero aún vale la pena mencionarlo.

Y otro precaución. Tenga cuidado usando el método ClearHeaders de la clase HttpResponse. Puede causarle algunos moretones si lo usa imprudentemente. Como me dio.

Después de redireccionar en el evento ActionFilterAttribute, las consecuencias de borrar todos los encabezados son perder todos los datos de sesión y los datos en el almacenamiento de TempData. Es más seguro redirigir desde una acción o no borrar encabezados cuando se realiza la redirección.

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

filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.AppendCacheExtension("no-store, must-revalidate");
 0
Author: user3253726,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-22 13:09:35

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

Código de ejemplo en Python usando web.py web.header las llamadas siguen. Redacté a propósito mi código personal irrelevante.


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

 0
Author: Richard Elkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-10 22:56:25

Vea este enlace a un Estudio de Caso sobre el Almacenamiento en caché:

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

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

 0
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-22 17:46:50