Come controlliamo la memorizzazione nella cache delle pagine Web, su tutti i browser?


1552

Le nostre indagini ci hanno mostrato che non tutti i browser rispettano le direttive della cache HTTP in modo uniforme.

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

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

Il nostro requisito è venuto da un test di sicurezza. Dopo la disconnessione dal nostro sito Web, è possibile premere il pulsante Indietro e visualizzare le pagine memorizzate nella cache.


Solo per ipad Safari, [this] [1] aiuta? [1]: stackoverflow.com/questions/24524248/…
Bakhshi,

Il più semplice sta usando: max-age = 10. Questo non è perfetto perché la pagina verrà memorizzata nella cache per 10 secondi. Ma è la minima soluzione "spaghettini". Inoltre, questo a volte fornisce un notevole aumento delle prestazioni su siti Web dinamici che utilizzano proxy inversi. (Il tuo script php lento verrà chiamato una volta ogni 10 secondi e verrà quindi memorizzato nella cache dal proxy inverso. Una volta ogni 10 secondi è molto meglio di una volta per visitatore)
Ciao mondo


3
Grazie per questa bella domanda. Per curiosità quale potrebbe essere la situazione che ti fa inviare alcuni dati mentre non vuoi che il destinatario li salvi per "motivi di sicurezza" . li hai già inviati!
Ragioniere م

1
@Accountant: nel suo scenario, l'utente si era disconnesso. Chi può garantire che il prossimo utente umano su tale User-Agent sarà la persona che si è appena disconnesso?
Fabien Haddadi,

Risposte:


2579

introduzione

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

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

È Cache-Controlconforme alle specifiche HTTP 1.1 per client e proxy (e implicitamente richiesto da alcuni client accanto Expires). È Pragmaconforme alle specifiche HTTP 1.0 per i client preistorici. Il Expiresè per HTTP 1.0 e 1.1 spec per i clienti e proxy. In HTTP 1.1, ha la Cache-Controlprecedenza 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 pubblicano solo pagine su HTTPS no-store, allora potresti ometterlo 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), allora potresti ometterlo Pragma.

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

Se non ti interessa nemmeno i proxy HTTP 1.0, potresti ometterti Expires.

Cache-Control: no-store, must-revalidate

D'altra parte, se il server include automaticamente Dateun'intestazione valida , è possibile anche teoricamente omettere Cache-Controle fare affidamento Expiressolo.

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

Ma ciò potrebbe non riuscire se, ad esempio, l'utente finale modifica la data del sistema operativo e il software client si basa su di essa.

Altri Cache-Controlparametri come max-agesono irrilevanti se Cache-Controlvengono specificati i parametri sopra menzionati . L' Last-Modifiedintestazione inclusa nella maggior parte delle altre risposte qui è interessante solo se si desidera effettivamente 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.NET Core v3

// using Microsoft.Net.Http.Headers
Response.Headers[HeaderNames.CacheControl] = "no-cache, no-store, must-revalidate";
Response.Headers[HeaderNames.Expires] = "0";
Response.Headers[HeaderNames.Pragma] = "no-cache";

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 / Pyramid:

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 il .htaccessfile Apache :

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

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 pubblicata su una connessione HTTP ed è presente un'intestazione sia nelle intestazioni della risposta HTTP che nei <meta http-equiv>tag HTML , quella specificata nell'intestazione della risposta HTTP avrà la precedenza sul meta tag HTML. Il meta tag HTML verrà utilizzato solo quando la pagina viene visualizzata da un file system del disco locale tramite un file://URL. Vedere anche il capitolo 5.2.2 delle specifiche HTML di W3 . Abbi 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 meta tag HTML per evitare confusione da parte dei principianti e fare affidamento su intestazioni di risposta HTTP rigide. Inoltre, in particolare quei <meta http-equiv>tag non sono validi in HTML5. Sono ammessi solo i http-equivvalori elencati nella specifica HTML5 .

Verifica delle intestazioni di risposta HTTP effettive

Per verificare l'uno e l'altro, è possibile visualizzarli / eseguirne il debug 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 della scheda "Rete" o "Rete", quindi facendo clic sulla richiesta HTTP di interesse per scoprire tutti i dettagli sulla richiesta e la risposta HTTP. Lo screenshot seguente è di Chrome:

Set di strumenti per sviluppatori Chrome Monitor del traffico HTTP che mostra le intestazioni di risposta HTTP su stackoverflow.com

Voglio impostare quelle intestazioni anche sui download di file

Prima di tutto, questa domanda e risposta sono indirizzate su "pagine web" (pagine HTML), non su "download di file" (PDF, zip, Excel, ecc.). Faresti meglio a memorizzarli nella cache e utilizzare un identificatore di versione del file da qualche parte nel percorso URI o nella querystring per forzare un nuovo download su un file modificato. Quando applichi comunque quelle intestazioni senza cache sui download di file, fai attenzione al bug IE7 / 8 quando offri un download di file su HTTPS anziché HTTP. Per i dettagli, vedere IE non può scaricare foo.jsf. Internet Explorer non è stato in grado di aprire questo sito Internet. Il sito richiesto non è disponibile o non può essere trovato .


16
Questo non sembra essere completo. Ho provato questa soluzione su Internet Explorer 8 e ho scoperto che il browser caricherà una versione cache quando premi il pulsante Indietro.
Mike Ottum,

16
Probabilmente la tua metodologia di test era sbagliata. Forse la pagina era già nella cache? Forse le intestazioni erano errate / sostituite? Forse stavi guardando la richiesta sbagliata? Ecc.
BalusC

8
In realtà, confermo che questo approccio è incompleto e causa problemi con IE8, o almeno in alcune circostanze. In particolare, quando si utilizza IE8 per recuperare una risorsa su SSL, IE8 rifiuta di recuperare la risorsa una seconda volta (o affatto, o dopo un primo tentativo, a seconda delle intestazioni utilizzate). Vedi il blog di EricLaw , per esempio.
haylem,

21
Vorrei aggiungere che questo è essenzialmente ciò che fa Bank of America. Se guardi le loro intestazioni di risposta e le traduci in aspx, stanno facendo: Response.AppendHeader ("Cache-Control", "no-cache, no-store, must-revalidate"); Response.AppendHeader ("Scadenza", "Gio, 01 dic 1994 16:00:00 GMT"); Immagino, se è abbastanza buono per loro, è abbastanza buono per me.
Giovanni,

8
@John: che scade l'intestazione è esattamente il valore di esempio nella specifica HTTP 1.0 . Funziona, ma è un po 'ridicolo prendere esattamente quel timestamp.
BalusC,

244

(ciao a tutti: per favore, non solo copiare e incollare senza ragione tutte le intestazioni che potete trovare)

Innanzitutto, la cronologia dei pulsanti 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 il testo era ancora più forte, dicendo esplicitamente ai browser di ignorare le direttive della cache per la cronologia dei pulsanti di ritorno.

Torna dovrebbe tornare indietro nel tempo (al momento in cui l'utente è stato registrato). Non passa a un URL aperto in precedenza.

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

  • La pagina deve essere consegnata su HTTPS , altrimenti questo busting della cache non sarà affidabile. Inoltre, se non stai utilizzando HTTPS, la tua pagina è vulnerabile al furto di accesso in molti altri modi.
  • Devi inviare Cache-Control: no-store, must-revalidate(alcuni browser osservano no-storee alcuni osservano must-revalidate)

Non hai mai bisogno di nessuno di:

  • <meta>con le intestazioni della cache - non funziona affatto. Totalmente inutile.
  • post-check/ pre-check- è solo la direttiva IE che si applica solo alle risorse memorizzabili .
  • Invio della stessa intestazione due volte o in dozzine di parti. Alcuni frammenti di PHP là fuori in realtà sostituiscono le intestazioni precedenti, risultando nell'invio solo dell'ultimo.

Se lo desideri, puoi aggiungere:

  • no-cacheoppure max-age=0, il che renderà "stantio" la risorsa (URL) e richiederà ai browser di verificare con il server se è disponibile una versione più recente ( no-storegià implica che ciò è ancora più forte).
  • Expirescon una data nel passato per i client HTTP / 1.0 (anche se al giorno d'oggi i veri client solo HTTP / 1.0 sono completamente inesistenti).

Bonus: il nuovo RFC di memorizzazione nella cache HTTP .


1
questo avrà qualche effetto collaterale sulle prestazioni del sito Web in termini di tempo di caricamento? in che modo no-store, no-cache, must-revalidate influisce sulle prestazioni?
Raman Ghai,

@RamanGhai Disabilitare la cache generalmente danneggia le prestazioni (e tutte e 3 le opzioni che hai menzionato disabilitano la memorizzazione nella cache). Potrebbe rendere inefficaci i CDN e i proxy ISP (ad es. Comunemente usati dagli operatori di telefonia mobile). Non danneggia il primo caricamento da parte di un nuovo utente (a parte il problema del proxy), ma la successiva navigazione potrebbe essere molto più lenta.
Kornel,

@porneL dichiari che dobbiamo inviare Cache-Control: must-revalidate. Perché non inviare Cache-Control: no-cachepoiché no-cacheimplica già must-revalidate? w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
Pacerier

3
@Pacerier la relazione di no-cachecon must-revalidateè vera per la cache, ma la cronologia non è una cache. Browser esplicito nel caso speciale must-revalidateper controllare il comportamento della cronologia .
Kornel,

@porneL, Hmm c'è un RFC di supporto che afferma che è il comportamento desiderato?
Pacerier,

103

Come affermato da @Kornel, quello che vuoi non è disattivare la cache, ma disattivare 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 da Cache-Control: no-store.

In FireFox (v23.0.1) funzionerà uno 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 di questi:

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

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

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

  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 per Chrome 28, FireFox 23, IE8, Safari 5.1.7 e Opera 12.15: Cache-Control: no-store, must-revalidate (solo https)

Si noti che https è necessario perché Opera non disattiva il buffer di cronologia per le semplici pagine http. Se davvero non riesci a ottenere https e sei pronto a ignorare Opera, il meglio che puoi fare è questo:

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

Di seguito mostra i registri non elaborati 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="">
    Fail: Opera 12.15
    Success: 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
    Success: 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: *
    Fail: Safari 5.1.7, Opera 12.15
    Success: Chrome 28, FireFox 23, IE8

  4. Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: Sat, 12 Oct 1991 05:00:00 GMT
    Pragma: no-cache
    Vary: *
    Fail: Safari 5.1.7, Opera 12.15
    Success: Chrome 28, FireFox 23, IE8

  5. Cache-Control: private, no-cache, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0
    Expires: 0
    Pragma: no-cache
    Vary: *
    <body onunload="">
    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Success: 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="">
    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Success: 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="">
    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Success: 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="">
    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Success: IE8

  9. Cache-Control: no-store
    Fail: Safari 5.1.7, Opera 12.15
    Success: Chrome 28, FireFox 23, IE8

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

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

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

  13. Pragma: no-cache
    Fallito: 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="">
    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Success: 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="">
    Fail: Chrome 28, FireFox 23, Safari 5.1.7, Opera 12.15
    Success: IE8

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

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

  18. 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
    Success: IE8

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

  3. Vary: *
    Fail: Chrome 28, Safari 5.1.7, Opera 12.15
    Success: FireFox 23, IE8

  4. Pragma: no-cache
    Fail: Chrome 28, Safari 5.1.7, Opera 12.15
    Success: FireFox 23, IE8

  5. Cache-Control: no-cache
    Fail: Chrome 28, Safari 5.1.7, Opera 12.15
    Success: FireFox 23, IE8

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

  7. 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
    Success: 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: *
    Fail: Chrome 28, Safari 5.1.7, Opera 12.15
    Success: FireFox 23, IE8

  9. Cache-Control: must-revalidate
    Fallimento: 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="">
    Fallimento: Chrome 28, FireFox 23, IE8, Safari 5.1.7
    Successo: Opera 12.15

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

  14. Cache-Control: no-store
    Fail: Opera 12.15
    Success: 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
    Success: 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
    Success: 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: *
    Fail: Chrome 28, Safari 5.1.7, Opera 12.15
    Success: FireFox 23, IE8

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

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

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

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

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


3
So che è stato pubblicato un paio di anni fa, ma è stata una lettura interessante. Questo problema mi sta facendo impazzire da alcuni mesi, il corpo sembra davvero sapere come gestire il controllo della cache. Ho visto alcune persone usare il <body onunload="">ma sembra più un modo per aggirare il problema reale. Ho provato a usare .htaccess e modificando le intestazioni in quel modo, se uso HTTPS dovrebbe funzionare in quel modo? È principalmente il safari in cui il problema si risolve maggiormente.
Giordania,

4
@Jordan, Per i registri sopra se hai HTTPS, l'aggiunta Cache-Control: no-storefarebbe il trucco. <body onunload="">è necessario solo quando non si dispone di HTTPS.
Pacerier,

37

Ho trovato utile il percorso web.config (ho provato ad aggiungerlo alla risposta ma non sembra essere stato accettato, quindi postando 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 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();
});

Per web.config modificherei solo un po 'per applicare le intestazioni personalizzate solo per quegli script che sappiamo essere caricati dinamicamente / usando requirejs. Supponendo che i tuoi script si trovino nella cartella client: <location path = "client"> ..... </location>
Ibrahim ben Salah

Per chi si sta chiedendo cosa web.confsia: sono le impostazioni principali e il file di configurazione di un'applicazione ASP.NETweb. È un documento XML che risiede nella directory principale. ( wiki ).
un altro

27

Ho scoperto che tutte le risposte in questa pagina hanno ancora problemi. In particolare, ho notato che nessuno di loro avrebbe impedito a IE8 di utilizzare una versione cache della pagina quando vi 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-store
Varia: *

Per una spiegazione dell'intestazione Vary, consultare 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 gennaio '10.

Su IE6 e Opera 9-10, premendo il pulsante Indietro è ancora possibile caricare la versione cache. Su tutti gli altri browser che ho testato, hanno scaricato una nuova versione dal server. Finora, non ho trovato alcun set di intestazioni che impediranno a quei browser di restituire versioni cache delle pagine 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 affinché 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 .


4
Questo funziona per il pulsante Indietro di IE8 !! Dopo aver provato tutto in ogni altro suggerimento, aggiungere l'intestazione "Vary: *" è apparentemente l'unica cosa che può costringere IE8 a ricaricare la pagina quando l'utente preme il pulsante Indietro. E questo fa il lavoro su HTTP / 1.1 server.
coredumperror,

In combinazione con le intestazioni suggerite da BarlusC, oltre a uno snippet JS che chiama window.location.reload () quando l'evento onPageShow si innesca con l'attributo "persistente" (necessario per Safari), ogni browser che ho testato forza un ricaricamento dal server quando l'utente utilizza il pulsante Indietro.
coredumperror,

1
@CoreDumpError, oh non dovresti supporre che JavaScript sia abilitato.
Pacerier,

@Pacerier Al momento in cui ho scritto la risposta nel 2010, questo ha funzionato su quelle che erano le ultime versioni di Safari e Opera, con il nostro server che si identificava come un server HTTP 1.0. Sfortunatamente, non ho più modo di testarlo più facilmente, quindi non posso dire nulla di definitivo sulle ultime versioni di questi browser.
Chris Vasselli,

Con quali versioni di browser hai provato?
Pacerier,

21

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


36
@bart: Ancora più problematico è che il 26 luglio 1997 è stato un sabato, non un lunedì ...
Cᴏʀʏ

5
Cache-Control: no-cachee Cache-Control: privatescontro: non dovresti mai metterli insieme: il primo dice ai browser e ai proxy di non memorizzare nella cache, il secondo dice ai proxy di non memorizzare nella cache, ma consente ai browser di conservare la propria copia privata. Non sono sicuro di quale impostazione seguirà il browser, ma è improbabile che sia coerente tra browser e versioni.
Keith,


questo non ha funzionato per me - usando asp.net 4.5 il codice viene eseguito ma non produce il risultato richiesto. Ho dovuto seguire questo: stackoverflow.com/questions/22443932/…
Andy,

8

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

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


4
Questo è un buon esempio del motivo per cui è necessario andare oltre le specifiche. Se le specifiche fossero sempre cristalline, non ci sarebbe molto senso per siti come StackOverflow. Da Microsoft Ai fini della retrocompatibilità con i server HTTP 1.0, Internet Explorer supporta un uso speciale dell'intestazione HTTP: no-cache. Se il client comunica con il server tramite una connessione protetta (https: //) e il server restituisce un'intestazione Pragma: no-cache con la risposta, Internet Explorer non memorizza nella cache la risposta.
michaelok,

@michaelok: il tuo riferimento è valido, ma manca il punto più grande: imposta un controllo cache / scade corretto e non hai bisogno di pragma.
EricLaw,

8

NOTA BENE: Consiglio vivamente di leggere la risposta di @ BalusC. Dopo aver letto il seguente tutorial di memorizzazione nella cache: http://www.mnot.net/cache_docs/ (ti consiglio di leggerlo anche io), ritengo che sia corretto. Tuttavia, per motivi storici (e poiché l'ho testato da solo), 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 testato 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 imposta due volte la stessa parte dell'intestazione, se falsenon viene inviato come secondo argomento alla funzione header, la funzione header sovrascriverà semplicemente la header()chiamata precedente . Quindi, quando si imposta il Cache-Control, ad esempio se uno non vuole mettere tutti gli argomenti in una 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 .


14
Questo è pieno di miti. pre-check e post-check sono solo IE, rilevanti solo per le risposte memorizzate nella cache, e il valore 0 è no-op. max-stale è l'intestazione della richiesta proxy, non l'intestazione della risposta del server. Scade accetta solo un singolo valore. Più di uno farà ignorare questa intestazione.
Kornel,

1
@porneL, invierai una risposta concorrenziale che affronta correttamente questi miti?
Pensando in modo strano il

@Oddthinking, si presenta come stackoverflow.com/questions/49547/... è una risposta in competizione.
Mike Ottum,

@Pacerier sì, come dico nel disclaimer, usa la risposta di BalusC.
Steven Oxley,

8

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 aggiungere questo da qualche parte dopo

app.UseStaticFiles();

Suggerirei di usare le costanti di Microsoft.Net.Http.Headers.HeaderNames invece dei letterali stringa "Cache-Controls", "Pragma" e "Expires".
Victor Sharovatov,

7

Queste direttive non mitigano alcun rischio per la sicurezza. Intendono davvero costringere gli UA ad aggiornare le informazioni volatili, non a impedire agli UA di conservare le informazioni. Vedi questa domanda simile . Per lo meno, non vi è alcuna garanzia che router, proxy, ecc. Non ignorino anche le direttive sulla cache.

Su una nota più positiva, le politiche relative all'accesso fisico ai computer, all'installazione del software e simili ti porteranno miglia 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 davvero fare è aiutarli a capire che una volta che le informazioni hanno colpito la loro macchina, quella macchina è la loro responsabilità, non la tua.


7

C'è un bug in IE6

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

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

È possibile disabilitare la compressione gzip per gli utenti IE6 (controllare l'agente utente per "MSIE 6")


6

RFC per HTTP 1.1 afferma che il metodo corretto consiste nell'aggiungere un'intestazione HTTP per:

Controllo cache: nessuna cache

I browser meno recenti potrebbero ignorarlo se non sono correttamente conformi a HTTP 1.1. Per quelli puoi provare l'intestazione:

Pragma: no-cache

Questo dovrebbe anche funzionare per i browser HTTP 1.1.


1
Le specifiche indicano che la risposta non deve essere riutilizzata senza riconvalida. È il Cache-Control: no-store che è il metodo ufficiale per indicare che la risposta non viene nemmeno memorizzata in una cache in primo luogo.
AnthonyWJones,

6

L'impostazione dell'intestazione http modificata su una data nel 1995 di solito fa il trucco.

Ecco un esempio:

Scadenza: mer, 15 nov 1995 04:58:08 GMT
Ultima modifica: mer, 15 nov 1995 04:58:08 GMT
Controllo cache: no-cache, must-revalidate

1
L'impostazione di un Last-Modified di lunga durata non ha alcun impatto sulla memorizzazione nella cache, a parte il fatto che una risposta memorizzata nella cache può essere utilizzata più a lungo a causa della riconvalida euristica.
EricLaw,

6

La documentazione di PHP per la funzione header 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 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);

11
Questo è ovviamente sbagliato. Le seconde chiamate a header () per Expires, Cache-control e Pragma sovrascrivono completamente i valori precedentemente impostati.
Kornel,

1
@porneL: No, non sovrascrivere i valori precedentemente impostati mentre passa false come secondo parametro, dicendo di non sovrascrivere i valori precedenti.
Julien Palard,

1
@JulienPalard la risposta è stata modificata dopo che ho fatto il mio commento. Non ha ancora molto senso.
Kornel,

Non inviare più intestazioni Cache-Control se si desidera lavorare in IE prima delle 9. Non inviare MAI pre-controllo o post-controllo. blogs.msdn.com/b/ieinternals/archive/2009/07/20/…
EricLaw

6

Se stai riscontrando problemi di download con IE6-IE8 su SSL e cache: intestazione no-cache (e valori simili) con file MS Office puoi usare cache: privato, intestazione no-store e file di ritorno su richiesta POST. Funziona.


6

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


Anche il mio problema con il browser mozilla 19.x è stato risolto dallo snippet di codice. autocomplete = "off". Grazie.
Satya,

5

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

E così via

La risposta accettata è corretta in quali intestazioni devono essere impostate, ma non in 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 si imposta Cache-controlsu no-cachee la seconda riga aggiunge gli altri attributino-store, must-revalidate


Questo funziona per me:Response.Cache.SetAllowResponseInBrowserHistory(false); Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
Vilx-

4

Ho ottenuto risultati migliori e più coerenti in tutti i browser impostando Pragma: no-cache


4

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

<body onunload=""> 

Questo hack sembra spezzare la cache di back-forward in Safari: c'è un evento di caricamento cross-browser quando si fa clic sul pulsante Indietro?


Bene, l'ho provato e questo funziona su Safari (5.1.7) ma non su Opera.
Pacerier,

4

Inoltre, solo per una buona misura, assicurati di reimpostare ExpiresDefaultnel tuo .htaccessfile se lo stai usando per abilitare la memorizzazione nella cache.

ExpiresDefault "access plus 0 seconds"

Successivamente, è possibile utilizzare ExpiresByTypeper impostare valori specifici per i file che si desidera memorizzare nella cache:

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

Questo può tornare utile se i tuoi file dinamici, ad esempio php, ecc., Vengono memorizzati nella cache dal browser e non riesci a capire perché. Controllare ExpiresDefault.


3

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


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

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

2

Per completare BalusC -> RISPOSTA Se si utilizza perl è possibile utilizzare 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 il META html, i browser li hanno ignorati e memorizzato nella cache della pagina.


0

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

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, che di solito non è desiderabile. La modifica delle intestazioni di risposta nel codice assicura che le immagini e i file di stile vengano memorizzati nella cache.

Questo è abbastanza ovvio, ma comunque degno di nota.

E un'altra cautela. Fare attenzione usando il metodo ClearHeaders dalla classe HttpResponse. Potrebbe darti qualche livido se lo usi incautamente. Come mi ha dato.

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

A pensarci bene, scoraggio tutti a usare 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");

0

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

web.headerSegue un esempio di codice in Python usando le chiamate web.py. Ho volutamente redatto il mio codice di utilità personale irrilevante.

    importare web
    import sys
    importare UTILITÀ PERSONALI

    myname = "main.py"

    urls = (
        '/', 'main_class'
    )

    main = web.application (urls, globals ())

    render = web.template.render ("templates /", base = "layout", cache = False)

    class main_class (oggetto):
        def GET (self):
            web.header ("Cache-control", "no-cache, no-store, must-revalidate")
            web.header ("Pragma", "no-cache")
            web.header ("Scade", "0")
            return render.main_form ()

        def POST (sé):
            msg = "POSTed:"
            form = web.input (function = None)
            web.header ("Cache-control", "no-cache, no-store, must-revalidate")
            web.header ("Pragma", "no-cache")
            web.header ("Scade", "0")
            return render.index_laid_out (greeting = msg + form.function)

    se __name__ == "__main__":
        nargs = len (sys.argv)
        # Assicurati che ci siano abbastanza argomenti dopo il nome del programma python
        se nargs! = 2:
            LOG-AND-DIE ("% s: errore della riga di comando, nargs =% s, dovrebbe essere 2", mio ​​nome, nargs)
        # Assicurarsi che il numero della porta TCP sia numerico
        provare:
            tcp_port = int (sys.argv [1])
        eccetto Eccezione come e:
            LOG-AND-DIE ("% s: tcp_port = int (% s) fallito (non un numero intero)", mio ​​nome, sys.argv [1])
        # Tutto bene!
        JUST-LOG ("% s: in esecuzione sulla porta% d", mio ​​nome, tcp_port)
        web.httpserver.runsimple (main.wsgifunc (), ("localhost", tcp_port))
        main.run ()


Questo non è già stato trattato molte volte nelle risposte che sono state sul sito per anni?
Martin Tournoij,

Le direttive META funzionano in Internet Explorer e nelle versioni di Edge 18 e precedenti. I browser moderni non li supportano. crbug.com/2763
EricLaw

0

Vedi questo link a un case study sulla memorizzazione nella cache:

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

Riepilogo, secondo l'articolo, Cache-Control: no-storefunziona solo su Chrome, Firefox e IE. IE accetta altri controlli, ma Chrome e Firefox no. Il link è una buona lettura completa della storia della memorizzazione nella cache e della documentazione di prova del concetto.


0

Non sono sicuro che la mia risposta sembri semplice e stupida, e forse ti è già nota da molto tempo fa, ma poiché impedire a qualcuno di utilizzare il pulsante Indietro del browser per visualizzare le tue pagine storiche è uno dei tuoi obiettivi, puoi utilizzare:

window.location.replace("https://www.example.com/page-not-to-be-viewed-in-browser-history-back-button.html");

Naturalmente, potrebbe non essere possibile implementarlo in tutto il sito, ma almeno per alcune pagine critiche, puoi farlo. Spero che sia di aiuto.


-1

puoi usare il blocco posizione per impostare singoli file invece che l'intera app ottiene la memorizzazione nella cache in IIS

 <location path="index.html">
    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Cache-Control" value="no-cache" />
        </customHeaders>
      </httpProtocol>
    </system.webServer>
  </location>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.