Le nostre indagini ci hanno mostrato che non tutti i browser rispettano le direttive della cache http in modo uniforms.
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:
Il nostro requisito proveniva da un test di sicurezza. Dopo aver effettuato il logout dal nostro sito Web, è ansible premere il pulsante Indietro e visualizzare le pagine memorizzate nella cache.
Il set minimo corretto di intestazioni che funziona tra tutti i client citati (e i proxy):
Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0
Cache-Control
è conforms alle specifiche HTTP 1.1 per client e proxy (e implicitamente richiesto da alcuni client accanto a Expires
). Il Pragma
è per la specifica HTTP 1.0 per i client preistorici. The Expires
è secondo le specifiche HTTP 1.0 e 1.1 per client e proxy. In HTTP 1.1, Cache-Control
ha la precedenza su Expires
, quindi dopo tutto è solo per i proxy HTTP 1.0.
Se non ti interessa IE6 e il suo caching rotto durante la pubblicazione di pagine su HTTPS con solo no-store
, puoi omettere Cache-Control: no-cache
.
Cache-Control: no-store, must-revalidate Pragma: no-cache Expires: 0
Se non ti interessa IE6 né i client HTTP 1.0 (HTTP 1.1 è stato introdotto nel 1997), potresti omettere Pragma
.
Cache-Control: no-store, must-revalidate Expires: 0
Se non ti interessa neanche i proxy HTTP 1.0, puoi omettere Expires
.
Cache-Control: no-store, must-revalidate
D’altra parte, se il server include automaticamente un’intestazione Date
valida, in teoria si può anche omettere Cache-Control
e si può contare solo su Expires
.
Date: Wed, 24 Aug 2016 18:32:02 GMT Expires: 0
Ma ciò potrebbe fallire se ad esempio l’utente finale manipola la data del sistema operativo e il software client si basa su di esso.
Altri parametri di Cache-Control
come max-age
sono irrilevanti se vengono specificati i parametri di Cache-Control
sopra menzionati. L’intestazione Last-Modified
inclusa nella maggior parte delle altre risposte qui è interessante solo se si desidera effettivamente memorizzare nella cache la richiesta, quindi non è necessario specificarla.
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.
Utilizzo di 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.
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.
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 / Pyramid:
request.response.headerlist.extend( ( ('Cache-Control', 'no-cache, no-store, must-revalidate'), ('Pragma', 'no-cache'), ('Expires', '0') ) )
Utilizzando 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.
Utilizzando il file .htaccess
Apache:
Header set Cache-Control "no-cache, no-store, must-revalidate" Header set Pragma "no-cache" Header set Expires 0
Utilizzando HTML4:
È importante sapere che quando una pagina HTML viene servita su una connessione HTTP e un’intestazione è presente sia nelle intestazioni delle risposte HTTP che nei tag HTML , allora l’intestazione specificata nell’intestazione della risposta HTTP avrà la precedenza sopra il meta tag HTML. Il meta tag HTML verrà utilizzato solo quando la pagina viene visualizzata dal file system del disco locale tramite un
file://
URL. Vedi anche W3 HTML spec capitolo 5.2.2 . Prenditi cura di questo quando non li specifichi a livello di codice, perché il server web può in particolare includere alcuni valori predefiniti.
In generale, è meglio non specificare i metatag HTML per evitare confusione tra gli avviatori e fare affidamento su intestazioni di risposta HTTP complesse. Inoltre, in particolare quei non sono validi in HTML5. Sono ammessi solo i valori
http-equiv
elencati nelle specifiche HTML5 .
Per verificare l’uno e l’altro, puoi vederli / debuggarli nel monitoraggio del traffico HTTP del set di strumenti per sviluppatori di webbrowser. Puoi arrivarci premendo F12 in Chrome / Firefox23 + / IE9 +, quindi aprendo il pannello “Rete” o “Rete”, quindi facendo clic sulla richiesta HTTP di interesse per scoprire tutti i dettagli sulla richiesta e risposta HTTP. Lo screenshot sottostante è di Chrome:
Prima di tutto, questa domanda e risposta è mirata su “pagine web” (pagine HTML), non su “download di file” (PDF, zip, Excel, ecc.). Faresti meglio a tenerli memorizzati nella cache e utilizzare qualche identificatore di versione del file da qualche parte nel percorso URI o querystring per forzare un nuovo download su un file modificato. Quando si applicano le intestazioni no-cache sui download di file in ogni caso, fare attenzione al bug di IE7 / 8 quando si serve un download di file su HTTPS anziché su HTTP. Per i dettagli, vedi IE non può scaricare foo.jsf. IE non è stato in grado di aprire questo sito internet. Il sito richiesto non è disponibile o non può essere trovato .
(ehi, tutti: per favore non copiare e incollare semplicemente tutte le intestazioni che riesci a trovare)
Prima di tutto, la cronologia del pulsante Indietro non è una cache :
Il modello di freschezza (Sezione 4.2) non si applica necessariamente ai meccanismi storici. Cioè, un meccanismo di cronologia può visualizzare una rappresentazione precedente anche se è scaduta.
Nella vecchia specifica HTTP la formulazione era ancora più forte, in quanto indicava esplicitamente ai browser di ignorare le direttive della cache per la cronologia dei pulsanti.
Back dovrebbe tornare indietro nel tempo (al momento in cui l’utente ha effettuato l’accesso). Non porta avanti a un URL aperto in precedenza.
Tuttavia, in pratica, la cache può influenzare il pulsante Indietro, in circostanze molto specifiche:
Cache-Control: no-store, must-revalidate
(alcuni browser osservano no-store
e alcuni osservano must-revalidate
) Non hai mai bisogno di nessuno di:
con le intestazioni della cache – non funziona affatto. Totalmente inutile. post-check
/ pre-check
– è la direttiva solo IE che si applica solo alle risorse intercambiabili . Se vuoi, puoi aggiungere:
no-cache
o max-age=0
, che renderà la risorsa (URL) “obsoleta” e richiederà ai browser di verificare con il server se c’è una versione più recente (il no-store
implica ancora di più). Expires
con una data nel passato per i client HTTP / 1.0 (anche se in questo momento i veri client HTTP / 1.0 sono completamente inesistenti). Bonus: la nuova cache RFC HTTP .
Come indicato in precedenza, ciò che si desidera non è distriggersre la cache, ma distriggersre il buffer della cronologia. Browser diversi hanno i loro modi sottili per disabilitare il buffer della cronologia.
In Chrome (v28.0.1500.95 m) possiamo farlo solo con Cache-Control: no-store
.
In FireFox (v23.0.1) ognuno di questi funzionerà:
Cache-Control: no-store
Cache-Control: no-cache
(solo https)
Pragma: no-cache
(solo https)
Vary: *
(solo https)
In Opera (v12.15) possiamo farlo solo con Cache-Control: must-revalidate
(solo https).
In Safari (v5.1.7, 7534.57.2) ognuno di questi funzionerà:
Cache-Control: no-store
in html
Cache-Control: no-store
(solo https)
In IE8 (v8.0.6001.18702IC) ognuno di questi funzionerà:
Cache-Control: must-revalidate, max-age=0
Cache-Control: no-cache
Cache-Control: no-store
Cache-Control: must-revalidate
Expires: 0
Cache-Control: must-revalidate
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Pragma: no-cache
(solo https)
Vary: *
(solo https)
La combinazione di quanto sopra ci offre questa soluzione che funziona per Chrome 28, FireFox 23, IE8, Safari 5.1.7 e Opera 12.15: Cache-Control: no-store, must-revalidate
(solo https)
Notare che https è necessario perché Opera non disabilita il buffer della cronologia per le semplici pagine http. Se davvero non riesci ad ottenere https e sei pronto a ignorare Opera, il meglio che puoi fare è questo:
Cache-Control: no-store
Di seguito sono riportati i log non elaborati dei miei test:
HTTP:
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Opera 12.15
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7
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: *
Fail: Opera 12.15
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7
Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Safari 5.1.7, Opera 12.15
Successo: Chrome 28, FireFox 23, IE8
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: *
Fail: Safari 5.1.7, Opera 12.15
Successo: Chrome 28, FireFox 23, IE8
Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
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: *
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
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: *
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: no-store
Fail: Safari 5.1.7, Opera 12.15
Successo: Chrome 28, FireFox 23, IE8
Cache-Control: no-store
Fail: Opera 12.15
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7
Cache-Control: no-cache
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Vary: *
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
Successo: nessuno
Pragma: no-cache
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
Successo: nessuno
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: *
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: must-revalidate, max-age=0
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: must-revalidate
Expires: 0
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: must-revalidate
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
Successo: IE8
Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
Pragma: no-cache
Vary: *
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
Successo: nessuno
HTTPS:
Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
Successo: nessuno
Cache-Control: private, max-age=0, proxy-revalidate, s-maxage=0
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
Successo: nessuno
Vary: *
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
Pragma: no-cache
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
Cache-Control: no-cache
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
Cache-Control: private, no-cache, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
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: *
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
Cache-Control: must-revalidate
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7
Successo: Opera 12.15
Cache-Control: private, must-revalidate, proxy-revalidate, s-maxage=0
Fail: Chrome 28, FireFox 23, IE8, Safari 5.1.7
Successo: Opera 12.15
Cache-Control: must-revalidate, max-age=0
Fail: Chrome 28, FireFox 23, Safari 5.1.7
Successo: IE8, Opera 12.15
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: *
Fail: Chrome 28, Safari 5.1.7
Successo: FireFox 23, IE8, Opera 12.15
Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Chrome 28, Safari 5.1.7
Successo: FireFox 23, IE8, Opera 12.15
Cache-Control: no-store
Fail: Opera 12.15
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7
Cache-Control: private, no-cache, no-store, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Pragma: no-cache
Vary: *
Fail: Opera 12.15
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7
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: *
Fail: Opera 12.15
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7
Cache-Control: private, no-cache
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Pragma: no-cache
Vary: *
Fail: Chrome 28, Safari 5.1.7, Opera 12.15
Successo: FireFox 23, IE8
Cache-Control: must-revalidate
Expires: 0
Fail: Chrome 28, FireFox 23, Safari 5.1.7,
Successo: IE8, Opera 12.15
Cache-Control: must-revalidate
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Fail: Chrome 28, FireFox 23, Safari 5.1.7,
Successo: IE8, Opera 12.15
Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: 0
Fail: Chrome 28, FireFox 23, Safari 5.1.7,
Successo: IE8, Opera 12.15
Cache-Control: private, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Fail: Chrome 28, FireFox 23, Safari 5.1.7,
Successo: IE8, Opera 12.15
Cache-Control: private, must-revalidate
Expires: Sat, 12 Oct 1991 05:00:00 GMT
Pragma: no-cache
Vary: *
Fail: Chrome 28, Safari 5.1.7
Successo: FireFox 23, IE8, Opera 12.15
Cache-Control: no-store, must-revalidate
Fail: nessuno
Successo: Chrome 28, FireFox 23, IE8, Safari 5.1.7, Opera 12.15
Ho trovato utile la rotta web.config (ho cercato di aggiungerla alla risposta ma non sembra essere stata accettata, quindi postare qui)
Ed ecco il modo express / node.js di 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 trovato che tutte le risposte su questa pagina avevano ancora problemi. In particolare, ho notato che nessuno di loro avrebbe impedito a IE8 di utilizzare una versione cache della pagina quando vi si accede premendo il pulsante Indietro.
Dopo molte ricerche e test, ho scoperto che le uniche due intestazioni di cui avevo veramente bisogno erano:
Cache-Control: no-store
Vary: *
Per una spiegazione dell’intestazione Vary, consulta 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 hanno causato la richiesta della pagina dal server quando si fa clic su un collegamento alla pagina o si inserisce l’URL direttamente nella barra degli indirizzi. Questo copre circa il 99% di tutti i browser in uso a partire da Jan ’10.
Su IE6 e su Opera 9-10, premendo il pulsante Indietro è ancora ansible caricare la versione memorizzata nella cache. Su tutti gli altri browser che ho provato, hanno recuperato una nuova versione dal server. Finora, non ho trovato alcuna serie di intestazioni che causerà quei browser per non restituire versioni di 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 sta identificando come un server HTTP 1.0. Le intestazioni che ho elencato sono quelle corrette in modo che le risposte da un server HTTP 1.0 non vengano memorizzate nella cache dai browser. Per un server HTTP 1.1, guarda la risposta di BalusC.
Dopo un po ‘di ricerche, abbiamo trovato il seguente elenco di intestazioni che sembrava coprire la maggior parte dei browser:
In ASP.NET abbiamo aggiunto questi utilizzando il seguente frammento:
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 favola. RFC2616 lo definisce solo come intestazione di richiesta
NOTA BENE: Consiglio vivamente di leggere la risposta di @ BalusC. Dopo aver letto il seguente tutorial sul caching: http://www.mnot.net/cache_docs/ (ti consiglio di leggerlo anch’io), credo che sia corretto. Tuttavia, per ragioni storiche (e perché l’ho testato io stesso), includerò la mia risposta originale qui sotto:
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 MYH:i:s') . ' GMT'); header ('Pragma: no-cache');
Questo dovrebbe funzionare Il problema era che quando si imposta la stessa parte dell’intestazione due volte, se il false
non viene inviato come secondo argomento della funzione di intestazione, la funzione di intestazione semplicemente sovrascriverà la chiamata header()
precedente header()
. Quindi, quando si imposta Cache-Control
, ad esempio se non si desidera mettere tutti gli argomenti in una chiamata di funzione header()
, 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
Il contenuto di “Content-Encoding: gzip” viene sempre memorizzato nella cache anche se si utilizza “Cache-Control: no-cache”.
http://support.microsoft.com/kb/321722
È ansible disabilitare la compressione gzip per gli utenti IE6 (controllare l’agente utente per “MSIE 6”)
RFC per HTTP 1.1 dice che il metodo corretto è quello di aggiungere un’intestazione HTTP per:
Cache-Control: no-cache
I browser meno recenti potrebbero ignorarlo se non sono adeguatamente conformi a HTTP 1.1. Per quelli puoi provare l’intestazione:
Pragma: no-cache
Questo dovrebbe funzionare anche per i browser HTTP 1.1.
Queste direttive non attenuano alcun rischio per la sicurezza. Esse sono concepite per forzare UA a aggiornare le informazioni volatili, non a mantenere le UA a conservare le informazioni. Vedi questa domanda simile . Per lo meno, non vi è alcuna garanzia che eventuali router, proxy, ecc. Non ignorino le direttive di memorizzazione nella cache.
In una nota più positiva, le politiche riguardanti l’accesso fisico ai computer, l’installazione del software e simili porteranno miglia di vantaggio sulla 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 le informazioni raggiungono la loro macchina, quella macchina è la loro responsabilità, non la tua.
La documentazione PHP per la funzione di intestazione ha un esempio piuttosto completo (fornito da 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 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);
Se si riscontrano problemi di download con IE6-IE8 su SSL e cache: intestazione no-cache (e valori simili) con i file MS Office è ansible utilizzare la cache: intestazione privata, no-store e file di ritorno su richiesta POST. Funziona.
nel mio caso risolvo il problema in chrome con questo
dove ho bisogno di cancellare il contenuto di un precedente modulo dati quando gli utenti fanno clic sul pulsante indietro per motivi di sicurezza
Per ASP.NET Core, crea una semplice class 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 registrarlo con Startup.cs
app.UseMiddleware();
Assicurati di aggiungerlo da qualche parte dopo
app.UseStaticFiles();
L’impostazione dell’intestazione http modificata in una data nel 1995 di solito fa il trucco.
Ecco un esempio:
Scadenza: mercoledì 15 novembre 1995 04:58:08 GMT Ultima modifica: mercoledì 15 novembre 1995 04:58:08 GMT Cache-Control: no-cache, must-revalidate
Ho ottenuto risultati migliori e più coerenti su tutti i browser impostando Pragma: no-cache
Le intestazioni nella risposta fornita da BalusC non impediscono a Safari 5 (e probabilmente 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 del gestore di eventi onunload vuoto al tag body:
Questo ha apparentemente interrotto la cache di back-forward in Safari: Esiste un evento onload cross-browser quando si fa clic sul pulsante Indietro?
The accepted answer does not appear to work for IIS7+, going by the large number of questions about cache headers not being sent in II7:
And so on
The accepted answer is correct in which headers must be set, but not in how they must be set. 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) 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 provare: 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()
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.