Domanda

Le nostre indagini ci hanno dimostrato che non tutti i browser rispettano in maniera uniforme le direttive della cache http.

Per motivi di sicurezza non vogliamo che alcune pagine della nostra applicazione vengano memorizzate nella cache, mai, dal browser web.Questo deve funzionare almeno per i seguenti browser:

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

La nostra esigenza deriva da un test di sicurezza.Dopo esserti disconnesso dal nostro sito web puoi premere il pulsante Indietro e visualizzare le pagine memorizzate nella cache.

È stato utile?

Soluzione

introduzione

Il set minimo corretto di intestazioni che funziona su tutti i client (e proxy) menzionati:

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

IL Cache-Control è conforme alle specifiche HTTP 1.1 per client e proxy (e implicitamente richiesto da alcuni client accanto a Expires).IL Pragma è conforme alle specifiche HTTP 1.0 per i client preistorici.IL Expires è conforme alle specifiche HTTP 1.0 e 1.1 per client e proxy.Nell'HTTP 1.1, il Cache-Control ha la precedenza su Expires, quindi dopo tutto è solo per i proxy HTTP 1.0.

Se non ti interessa IE6 e la sua memorizzazione nella cache interrotta quando si servono pagine su HTTPS con solo no-store, allora potresti omettere Cache-Control: no-cache.

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

Se non ti interessano i client IE6 né HTTP 1.0 (HTTP 1.1 è stato introdotto nel 1997), potresti omettere Pragma.

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

Se non ti interessano nemmeno i proxy HTTP 1.0, puoi omettere Expires.

Cache-Control: no-store, must-revalidate

D'altra parte, se il server include automaticamente un file valid Date header, allora potresti teoricamente ometterlo Cache-Control anche tu e fare affidamento su Expires soltanto.

Date: Wed, 24 Aug 2016 18:32:02 GMT
Expires: 0

Ma ciò potrebbe fallire se ad es.l'utente finale manipola la data del sistema operativo e il software client fa affidamento su di essa.

Altro Cache-Control parametri come max-age sono irrilevanti se quanto sopra menzionato Cache-Control vengono specificati i parametriIL Last-Modified l'intestazione inclusa nella maggior parte delle altre risposte ecco soltanto interessante se tu volere davvero per memorizzare nella cache la richiesta, quindi non è necessario specificarla affatto.

Come impostarlo?

Utilizzando PHP:

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

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

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

Utilizzo dell'API Web ASP.NET:

// `response` is an instance of System.Net.Http.HttpResponseMessage
response.Headers.CacheControl = new CacheControlHeaderValue
{
    NoCache = true,
    NoStore = true,
    MustRevalidate = true
};
response.Headers.Pragma.ParseAdd("no-cache");
// We can't use `response.Content.Headers.Expires` directly
// since it allows only `DateTimeOffset?` values.
response.Content?.Headers.TryAddWithoutValidation("Expires", 0.ToString()); 

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

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

Utilizzando Ruby on Rails o Python/Flask:

headers["Cache-Control"] = "no-cache, no-store, must-revalidate" # HTTP 1.1.
headers["Pragma"] = "no-cache" # HTTP 1.0.
headers["Expires"] = "0" # Proxies.

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

Utilizzando Python/Piramide:

request.response.headerlist.extend(
    (
        ('Cache-Control', 'no-cache, no-store, must-revalidate'),
        ('Pragma', 'no-cache'),
        ('Expires', '0')
    )
)

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

Utilizzando Apache .htaccess file:

<IfModule mod_headers.c>
    Header set Cache-Control "no-cache, no-store, must-revalidate"
    Header set Pragma "no-cache"
    Header set Expires 0
</IfModule>

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

Meta tag HTML e intestazioni di risposta HTTP

È importante sapere che quando una pagina HTML viene servita tramite una connessione HTTP ed è presente un'intestazione Entrambi le intestazioni di risposta HTTP e l'HTML <meta http-equiv> tag, quello specificato nell'intestazione della risposta HTTP avrà la precedenza sul meta tag HTML.Il meta tag HTML verrà utilizzato solo quando la pagina viene visualizzata dal file system del disco locale tramite a file:// URL.Guarda anche Specifiche HTML W3 capitolo 5.2.2.Fai attenzione quando non li specifichi a livello di codice, perché il server web può includere alcuni valori predefiniti.

In generale, faresti meglio a farlo non specificare i meta tag HTML per evitare confusione da parte dei principianti e fare affidamento su intestazioni di risposta HTTP rigide.Inoltre, in particolare quelli <meta http-equiv> i tag sono non valido nell'HTML5.Solo il http-equiv valori elencati in Specifica HTML5 sono ammessi.

Verifica delle intestazioni di risposta HTTP effettive

Per verificare l'uno e l'altro, puoi visualizzarli/eseguirne il debug nel monitor del traffico HTTP del set di strumenti per sviluppatori del browser web.Puoi arrivarci premendo F12 in Chrome/Firefox23+/IE9+, quindi aprendo il pannello della scheda "Rete" o "Rete" e quindi facendo clic sulla richiesta HTTP di interesse per scoprire tutti i dettagli sulla richiesta e risposta HTTP.IL sotto lo screenshot proviene da Chrome:

Chrome developer toolset HTTP traffic monitor showing HTTP response headers on stackoverflow.com

Voglio impostare quelle intestazioni anche sui download di file

Prima di tutto, questa domanda e risposta è mirata alle "pagine web" (pagine HTML), non ai "download di file" (PDF, zip, Excel, ecc.).Faresti meglio a memorizzarli nella cache e utilizzare qualche identificatore di versione del file da qualche parte nel percorso URI o nella stringa di query per forzare un nuovo download su un file modificato.Quando si applicano comunque queste intestazioni senza cache sui download di file, fare attenzione al bug IE7/8 quando si serve un download di file su HTTPS anziché su HTTP.Per i dettagli, vedere IE non può scaricare foo.jsf.IE non è riuscito ad aprire questo sito Internet.Il sito richiesto non è disponibile o non è stato trovato.

Altri suggerimenti

(Ciao a tutti:per favore non copiare e incollare senza pensarci tutte le intestazioni che riesci a trovare)

Prima di tutto, La cronologia del pulsante Indietro è non una cache:

Il modello della freschezza (sezione 4.2) non si applica necessariamente ai meccanismi storici.Cioè, un meccanismo di cronologia può visualizzare una rappresentazione precedente anche se è scaduta.

Nelle vecchie specifiche HTTP la formulazione era ancora più forte, dicendo esplicitamente ai browser di ignorare le direttive della cache per la cronologia dei pulsanti Indietro.

Back dovrebbe tornare indietro nel tempo (al momento in cui l'utente era connesso).Non passa a un URL aperto in precedenza.

Tuttavia, in pratica, la cache può influenzare il pulsante Indietro, in circostanze molto specifiche:

  • Pagina dovere essere consegnato HTTPS, altrimenti il ​​busting della cache non sarà affidabile.Inoltre, se non utilizzi HTTPS, la tua pagina è vulnerabile al furto dell'accesso in molti altri modi.
  • Devi inviare Cache-Control: no-store, must-revalidate (alcuni browser osservano no-store e alcuni osservano must-revalidate)

Voi Mai bisogno di uno di:

  • <meta> con intestazioni della cache: non funziona affatto.Totalmente inutile.
  • post-check/pre-check - è una direttiva solo IE che si applica solo a cachable risorse.
  • Invio della stessa intestazione due volte o in dozzine di parti.Alcuni snippet PHP disponibili sostituiscono effettivamente le intestazioni precedenti, con il risultato che viene inviato solo l'ultimo.

Se vuoi potresti aggiungere:

  • no-cache O max-age=0, che renderà la risorsa (URL) "obsoleta" e richiederà ai browser di verificare con il server se è disponibile una versione più recente (no-store già lo implica ancora più forte).
  • Expires con una data nel passato per i client HTTP/1.0 (anche se vero Al giorno d'oggi i client solo HTTP/1.0 sono completamente inesistenti).

Bonus: La nuova RFC per la memorizzazione nella cache HTTP.

Come affermato da pornoL, quello che vuoi non è disattivare la cache, ma disattivare il buffer della cronologia.Diversi browser hanno i propri modi sottili per disabilitare il buffer della cronologia.

In Chrome (v28.0.1500.95 m) possiamo farlo solo tramite Cache-Control: no-store.

In FireFox (v23.0.1) funzionerà uno qualsiasi di questi:

  1. Cache-Control: no-store

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

  3. Pragma: no-cache (solo https)

  4. Vary: * (solo https)

In Opera (v12.15) possiamo farlo solo tramite Cache-Control: must-revalidate (solo https).

In Safari (v5.1.7, 7534.57.2) funzionerà uno qualsiasi di questi:

  1. Cache-Control: no-store
    <body onunload=""> nell'HTML

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

In IE8 (v8.0.6001.18702IC) funzionerà uno qualsiasi di questi:

  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 combinazione di quanto sopra ci dà questa soluzione che funziona con Chrome 28, FireFox 23, IE8, Safari 5.1.7 e Opera 12.15: Cache-Control: no-store, must-revalidate (solo https)

Tieni presente che https è necessario perché Opera non disattiverebbe il buffer della cronologia per le semplici pagine http.Se davvero non riesci a ottenere https e sei pronto a ignorare Opera, la cosa migliore che puoi fare è questa:

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

Di seguito sono riportati i registri grezzi dei miei test:

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="">
    Fallire:Opera 12.15
    Successo: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="">
    Fallire:Opera 12.15
    Successo: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: *
    Fallire:Safari 5.1.7, Opera 12.15
    Successo: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: *
    Fallire:Safari 5.1.7, Opera 12.15
    Successo: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="">
    Fallire:Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Successo: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="">
    Fallire:Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Successo: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="">
    Fallire:Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Successo: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="">
    Fallire:Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Successo:IE8

  9. Cache-Control: no-store
    Fallire:Safari 5.1.7, Opera 12.15
    Successo:Cromo 28, FireFox 23, IE8

  10. Cache-Control: no-store
    <body onunload="">
    Fallire:Opera 12.15
    Successo:Chrome 28, FireFox 23, IE8, Safari 5.1.7

  11. Cache-Control: no-cache
    Fallire:Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Successo:IE8

  12. Vary: *
    Fallire:Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Successo:nessuno

  13. Pragma: no-cache
    Fallire:Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
    Successo:nessuno

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

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

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

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

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

HTTPS:

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

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

  3. Vary: *
    Fallire:Chrome 28, Safari 5.1.7, Opera 12.15
    Successo:FireFox23, IE8

  4. Pragma: no-cache
    Fallire:Chrome 28, Safari 5.1.7, Opera 12.15
    Successo:FireFox23, IE8

  5. Cache-Control: no-cache
    Fallire:Chrome 28, Safari 5.1.7, Opera 12.15
    Successo:FireFox23, IE8

  6. Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
    Fallire:Chrome 28, Safari 5.1.7, Opera 12.15
    Successo:FireFox23, IE8

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

  9. Cache-Control: must-revalidate
    Fallire:Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Successo:Opera 12.15

  10. Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
    <body onunload="">
    Fallire:Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Successo:Opera 12.15

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

  14. Cache-Control: no-store
    Fallire:Opera 12.15
    Successo: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="">
    Fallire:Opera 12.15
    Successo: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="">
    Fallire:Opera 12.15
    Successo: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: *
    Fallire:Chrome 28, Safari 5.1.7, Opera 12.15
    Successo:FireFox23, IE8

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

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

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

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

  23. Cache-Control: no-store, must-revalidate
    Fallire:nessuno
    Successo:Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15

Ho trovato utile il percorso web.config (ho provato ad aggiungerlo alla risposta ma non sembra essere stato accettato, quindi pubblicalo qui)

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

Ed ecco il modo express/node.js per fare lo stesso:

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

Ho scoperto che tutte le risposte in questa pagina presentavano ancora problemi.In particolare, ho notato che nessuno di loro impediva a IE8 di utilizzare una versione memorizzata nella cache della pagina quando si accedeva premendo il pulsante Indietro.

Dopo molte ricerche e test, ho scoperto che le uniche due intestazioni di cui avevo veramente bisogno erano:

Controllo cache:no-negozio
Variare:*

Per una spiegazione dell'intestazione Vary, controlla http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.6

Su IE6-8, FF1.5-3.5, Chrome 2-3, Safari 4 e Opera 9-10, queste intestazioni facevano sì che la pagina venisse richiesta dal server quando si fa clic su un collegamento alla pagina o si inserisce l'URL direttamente nella barra degli indirizzi.Questo copre circa 99% di tutti i browser in uso a partire da gennaio '10.

Su IE6 e Opera 9-10, premendo il pulsante Indietro veniva comunque caricata la versione memorizzata nella cache.Su tutti gli altri browser che ho testato, hanno recuperato una nuova versione dal server.Finora, non ho trovato alcun set di intestazioni che impedisca a questi browser di restituire versioni delle pagine memorizzate nella cache quando si preme il pulsante Indietro.

Aggiornamento: Dopo aver scritto questa risposta, mi sono reso conto che il nostro server web si identifica come server HTTP 1.0.Le intestazioni che ho elencato sono quelle corrette affinché le risposte da un server HTTP 1.0 non vengano memorizzate nella cache dai browser.Per un server HTTP 1.1, guarda BalusC risposta.

Dopo un po' di ricerca abbiamo creato il seguente elenco di intestazioni che sembravano coprire la maggior parte dei browser:

In ASP.NET li abbiamo aggiunti utilizzando il seguente snippet:

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 

Trovato da: http://forums.asp.net/t/1013531.aspx

L'uso dell'intestazione pragma nella risposta è una storia di mogli.RFC2616 lo definisce solo come intestazione della richiesta

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

DISCLAIMER:Consiglio vivamente di leggere la risposta di @BalusC.Dopo aver letto il seguente tutorial sulla memorizzazione nella cache: http://www.mnot.net/cache_docs/ (Vi consiglio di leggerlo anche voi), credo che sia corretto.Tuttavia, per ragioni storiche (e poiché l'ho testato personalmente), includerò la mia risposta originale di seguito:


Ho provato la risposta "accettata" per PHP, che non ha funzionato per me.Poi ho fatto una piccola ricerca, ho trovato una leggera variante, l'ho testata e ha funzionato.Ecco qui:

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

Dovrebbe funzionare.Il problema era che quando si impostava la stessa parte dell'intestazione due volte, se il file false non viene inviato come secondo argomento alla funzione di intestazione, la funzione di intestazione sovrascriverà semplicemente il precedente header() chiamata.Quindi, quando si imposta il file Cache-Control, ad esempio se non si vogliono riunire tutti gli argomenti in uno solo header() chiamata di funzione, deve fare qualcosa del genere:

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

Vedi la documentazione più completa Qui.

C'è un bug in IE6

Contenuti con "Codifica contenuto:gzip" viene sempre memorizzato nella cache anche se si utilizza "Cache-Control:senza cache".

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

Puoi disabilitare la compressione gzip per gli utenti IE6 (controlla l'agente utente per "MSIE 6")

Per ASP.NET Core, creare una semplice classe middleware:

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

quindi registralo con Startup.cs

app.UseMiddleware<NoCacheMiddleware>();

Assicurati di aggiungerlo da qualche parte dopo

app.UseStaticFiles();

La RFC per HTTP 1.1 dice che il metodo corretto è aggiungere un'intestazione HTTP per:

Controllo cache:senza cache

I browser più vecchi potrebbero ignorarlo se non sono adeguatamente conformi a HTTP 1.1.Per quelli puoi provare l'intestazione:

Pragma:senza cache

Questo dovrebbe funzionare anche per i browser HTTP 1.1.

Queste direttive non mitigano alcun rischio per la sicurezza.In realtà hanno lo scopo di forzare gli UA ad aggiornare le informazioni volatili, non di impedire agli UA di conservare le informazioni.Vedere questa domanda simile.Per lo meno, non vi è alcuna garanzia che eventuali router, proxy, ecc.non ignorerà anche le direttive di memorizzazione nella cache.

Passando ad una nota più positiva, le politiche riguardanti l’accesso fisico ai computer, l’installazione di software e simili ti metteranno molto più avanti rispetto alla maggior parte delle aziende in termini di sicurezza.Se i consumatori di queste informazioni sono membri del pubblico, l’unica cosa che puoi veramente fare è aiutarli a capire che una volta che l’informazione arriva sulla loro macchina, quella macchina viene loro responsabilità, non tua.

Impostare l'intestazione http modificata su una data nel 1995 di solito risolve il problema.

Ecco un esempio:

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

IL Documentazione PHP per la funzione header ha un esempio piuttosto completo (contributo di una terza parte):

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

Se riscontri problemi di download con IE6-IE8 su SSL e cache:no-cache header (e valori simili) con file MS Office, puoi utilizzare cache:private,no-store header e restituire il file su richiesta POST.Funziona.

nel mio caso risolvo il problema in Chrome con questo

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

dove devo cancellare il contenuto dei dati di un modulo precedente quando gli utenti fanno clic sul pulsante Indietro per motivi di sicurezza

Ho avuto risultati migliori e più coerenti su tutti i browser impostando Pragma:senza cache

Le intestazioni nella risposta fornita da BalusC non impediscono a Safari 5 (e forse anche alle versioni precedenti) di visualizzare il contenuto dalla cache del browser quando si utilizza il pulsante Indietro del browser.Un modo per evitare ciò è aggiungere un attributo vuoto del gestore eventi onunload al tag body:

<body onunload=""> 

A quanto pare questo hack rompe la cache back-forward in Safari: Si verifica un evento di caricamento su più browser quando si fa clic sul pulsante Indietro?

La risposta accettata non sembra funzionare per IIS7+, considerando il gran numero di domande sulle intestazioni della cache non inviate in II7:

E così via

La risposta accettata è corretta in merito a quali intestazioni devono essere impostate, ma non a come devono essere impostate.In questo modo funziona con IIS7:

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

La prima riga viene impostata Cache-control A no-cache, e la seconda riga aggiunge gli altri attributi no-store, must-revalidate

Inoltre, solo per buona misura, assicurati di reimpostare il file ExpiresDefault nel tuo .htaccess file se lo stai utilizzando per abilitare la memorizzazione nella cache.

ExpiresDefault "access plus 0 seconds"

Successivamente è possibile utilizzare ExpiresByType per impostare valori specifici per i file che desideri memorizzare nella cache:

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

Ciò può tornare utile anche se i tuoi file dinamici, ad es.php, ecc.vengono memorizzati nella cache dal browser e non riesci a capire il motivo.Controllo ExpiresDefault.

Oltre alle intestazioni, considera di pubblicare la tua pagina tramite https.Molti browser non memorizzano nella cache https per impostazione predefinita.

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

// In .net webform
<%@ OutputCache NoStore="true" Duration="0" VaryByParam="*" %>

Completare Balus C -> RISPOSTASe stai usando Perl puoi usare CGI per aggiungere intestazioni HTTP.

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

Utilizzando 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: Quando ho provato a utilizzare META html, i browser li hanno ignorati e hanno memorizzato la pagina nella cache.

Voglio solo sottolineare che se qualcuno vuole impedire la memorizzazione nella cache SOLO di contenuti dinamici, l'aggiunta di tali intestazioni aggiuntive dovrebbe essere effettuata a livello di codice.

Ho modificato il file di configurazione del mio progetto per aggiungere intestazioni senza cache, ma ciò ha anche disabilitato la memorizzazione nella cache del contenuto statico, cosa che di solito non è desiderabile.La modifica delle intestazioni di risposta nel codice garantisce che le immagini e i file di stile verranno memorizzati nella cache.

Questo è abbastanza ovvio, ma vale comunque la pena menzionarlo.

E un'altra avvertenza.Fare attenzione all'utilizzo del metodo ClearHeaders dalla classe HttpResponse.Potrebbe provocarti qualche livido se lo usi incautamente.Come mi ha dato.

Dopo il reindirizzamento sull'evento ActionFilterAttribute, le conseguenze della cancellazione di tutte le intestazioni comportano la perdita di tutti i dati della sessione e dei dati nell'archivio TempData.È più sicuro reindirizzare da un'azione o non cancellare le intestazioni durante il reindirizzamento.

Ripensandoci, sconsiglio tutti di utilizzare il metodo ClearHeaders.È meglio rimuovere le intestazioni separatamente.E per impostare correttamente l'intestazione Cache-Control sto usando questo codice:

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

Non ho avuto fortuna con <head><meta> elementi.L'aggiunta diretta di parametri relativi alla cache HTTP (al di fuori del documento HTML) funziona davvero per me.

Codice di esempio in Python utilizzando web.py web.header seguono le chiamate.Ho oscurato di proposito il mio codice di utilità personale e irrilevante.

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

Vedere questo collegamento a un caso di studio sulla memorizzazione nella cache:

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

Riepilogo, secondo l'articolo, solo Cache-Control: no-store funziona su Chrome, Firefox e IE.IE accetta altri controlli, ma Chrome e Firefox no.Il collegamento è una buona lettura completo della cronologia della memorizzazione nella cache e della documentazione della prova di concetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top