9

Esiste un modo per forzare i client di una pagina Web a ricaricare la cache (ad esempio immagini, javascript, ecc.) Dopo che un server ha inviato un aggiornamento al codice base? Riceviamo molte chiamate all'help desk chiedendo perché certe funzionalità non funzionano più. Un semplice aggiornamento duro risolve i problemi mentre scarica il file javascript appena aggiornato.Forza il browser per ricaricare tutta la cache dopo l'aggiornamento del sito

Per specifiche utilizziamo Glassfish 3.x. e JSF 2.1.x. Ciò si applicherebbe non solo a JSF, naturalmente.

Per descrivere cosa comportamento Spero che è possibile:

sito A ha due immagini e due file JavaScript. Un utente visita il sito e i 4 file vengono memorizzati nella cache. Per quanto mi riguarda, non c'è bisogno di "scaricare di nuovo" i file, a meno che l'utente non costringa in modo specifico un aggiornamento "duro" o cancelli la cache. Una volta che un sito ha inviato un aggiornamento a uno dei file, il server potrebbe avere una sorta di metadati nell'intestazione che informa il client di detto aggiornamento. Se il cliente sceglie, i nuovi file verranno scaricati.

Quello che non voglio fare è mettere il meta-tag nell'intestazione di una pagina per forzare la memorizzazione di niente dalla cache ... Voglio solo qualcosa che dice al client che si è verificato un aggiornamento e che dovrebbe ottenere il l'ultima volta che qualcosa è stato aggiornato. Suppongo che questo sarebbe solo una sorta di controllo delle versioni sul lato client.

Grazie per il vostro tempo!

risposta

12

Il modo corretto per gestirlo è con la modifica della convenzione URL per le risorse. Ad esempio, abbiamo come:

/resources/js/fileName.js 

Per arrivare al browser di memorizzare nella cache ancora il file, ma farlo nel modo corretto con il controllo delle versioni, è con l'aggiunta di qualcosa per l'URL. L'aggiunta di un valore a querystring non consente la memorizzazione nella cache, quindi il posto in cui inserirlo è dopo /resources/.

Un riferimento per il caching querystring: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.9

Così, per esempio, i tuoi URL sarà simile:

/resources/1234/js/fileName.js 

Allora, cosa si può fare è utilizzare il numero di versione del progetto (o di qualche valore in una proprietà/config file che si modifica manualmente quando si desidera ricaricare i file memorizzati nella cache) poiché questo numero deve cambiare solo quando il progetto viene modificato. Quindi il tuo URL potrebbe avere:

/resources/cacheholder${project.version}/js/fileName.js 

Questo dovrebbe essere abbastanza facile.

Il problema è ora con la mappatura dell'URL, poiché tale valore nel mezzo è dinamico. Il modo in cui abbiamo superato questo è con un modulo di riscrittura degli URL che ci ha permesso di filtrare gli URL prima che arrivassero alla nostra applicazione.La riscrittura osservò per gli URL che sembravano:

/resources/cacheholder______/whatever 

e rimosso la parte cacheholder_______/. Dopo la riscrittura, sembrava una normale richiesta, e il server avrebbe risposto con il file corretto, senza nessun'altra specifica mappatura/logica ... il punto è che il browser pensava che fosse un nuovo file (anche se in realtà non lo era t), quindi lo ha richiesto, e il server lo calcola e serve il file corretto (anche se è un URL "strano").

Ovviamente, un'altra opzione è quella di aggiungere questa stringa dinamica al nome file stesso e quindi utilizzare lo strumento di riscrittura per rimuoverlo. In ogni caso, la stessa cosa è fatta: prendere di mira una stringa di testo durante la riscrittura e rimuoverla. Questo ti permette di ingannare il browser, ma non il server :)


UPDATE:

Un'alternativa che mi piace molto è quello di impostare il nome del file in base al contenuto, e cache che. Ad esempio, ciò potrebbe essere fatto con un hash. Ovviamente, questo tipo di cose non è qualcosa che dovresti fare manualmente e salvare nel tuo progetto (si spera); è qualcosa che la tua applicazione/struttura dovrebbe gestire. Per esempio, in Grails, c'è un plugin che "hash e le cache" risorse, in modo che si verifica quanto segue:

  • Ogni risorsa è controllato
  • Un nuovo file (o la mappatura a questo file) viene creato, con un nome che è l'hash del suo contenuto
  • Quando si aggiunge <script>/<link> tag alla tua pagina, il nome hash viene utilizzato
  • Quando viene richiesto il file hash nome, serve la risorsa originale
  • l'hashing il file nominato viene memorizzato nella cache "per sempre"

L'aspetto interessante di questa configurazione è che non è necessario preoccuparsi della memorizzazione nella cache in modo corretto: è sufficiente impostare i file nella cache per sempre e l'hashing deve occuparsi della disponibilità di file/mapping in base al contenuto. Fornisce inoltre la possibilità per i rollback/annullamenti di essere già memorizzati nella cache e caricati rapidamente.

+0

"L'aggiunta di un valore a querystring non consente la memorizzazione nella cache" - dalla documentazione che ho letto, tale affermazione è imprecisa. HTTP GET _are_ memorizzati nella cache dal browser, con o senza una stringa di query. Vedere http://www.w3schools.com/tags/ref_httpmethods.asp – pmont

+0

@pmont Si prega di non fare riferimento a W3Schools sulla documentazione W3 attuale. Il tuo punto non è valido, ti preghiamo di leggere il link che ho postato o di fornire qualcosa di più legittimo. – Ian

+0

Non c'è bisogno di arrabbiarmi con me. I server Web che ho distribuito hanno tutti gli URL di query memorizzati nella cache. Quali server/e avete osservato di non averli memorizzati nella cache? Dal tuo link: "Questo significa in particolare che le risposte dai server HTTP/1.0 per tali URI NON DOVREBBERO essere prese da una cache." "Forse le modifiche in HTTP/1.1 potrebbero spiegare il diverso comportamento? – pmont

0

ho utilizzare un parametro no-cache per queste situazioni ... un avere una stringa come valore costante (dal file di configurazione)

$no_cache = "v11"; 

e nelle pagine, io uso le attività come

<img src="a.jpg?nc=$no_cache"> 

e quando aggiorno il mio codice, basta cambiare il valore $ no_cache e funziona come un incantesimo.

+0

Ma come hai fatto notare, questo non consente mai di memorizzare la risorsa nella cache. perchè vorresti questo? – Ian

+0

se non si modifica il valore no_cache, i file statici verranno memorizzati nella cache. fai il cambiamento solo quando hai cambiato roba statica. – tanaydin

+0

No, non è vero. Qualsiasi cosa con una querystring non dovrebbe essere memorizzata nella cache, secondo le specifiche HTTP. Alcuni browser seguono questo, altri no. Quindi il browser farà sempre la richiesta dato che alla fine c'è una querystring. Il server potrebbe averlo memorizzato nella cache, che è bello, ma non è ancora memorizzato nella cache del client. – Ian

Problemi correlati