2012-10-25 10 views
9

Sto sviluppando un'app Web utilizzando GWT e vedo un pazzo problema con il caching del file app.nocache.js nel browser anche se il server Web ha inviato una nuova copia del file!Come bloccare il browser nella cache GWT nocache.js

Sto utilizzando Eclipse per compilare l'app, che funziona in modalità dev. Per testare la modalità di produzione, ho una macchina virtuale (Oracle VirtualBox) con un sistema operativo guest Ubuntu in esecuzione sul mio computer host (Windows 7). Sto eseguendo il server web lighttpd nella VM. La VM condivide la directory di guerra del mio progetto e il server web sta servendo questa directory.

Sto utilizzando Chrome come browser, ma la stessa cosa accade in Firefox.

Ecco lo scenario:

  • La pagina web per l'applicazione è vuota. Accorind allo strumento "Ispeziona elemento" di Chrome, è perché sta cercando di recuperare 6E89D5C912DD8F3F806083C8AA626B83.cache.html, che non esiste (404 not found).
  • Controllo la directory di guerra, e abbastanza sicuro, che il file non esiste.
  • Il app.nocache.js sul browser È STATO RICARICATO dal server Web (200 OK), perché il file sul server era più recente della cache del browser. Ho verificato che la dimensione del file e il timestamp per il nuovo file restituito dal server fossero corretti. (Si tratta di informazioni sui report di Chrome sulla risposta HTTP del server)
  • Tuttavia, se apro lo app.nocache.js nel browser, il javascript si riferisce a 6E89D5C912DD8F3F806083C8AA626B83.cache.html !!! Cioè, anche se il server Web ha inviato un nuovo app.nocache.js, il browser sembra averlo ignorato e ha continuato a utilizzare la sua copia cache!

  • Goto Google-> GWT Compila in Eclipse. Ricompila il tutto.

  • Verificare nella directory war che app.nocache.js sia stato sovrascritto e abbia un nuovo timestamp.
  • Ricarica la pagina da Chrome e verifica ancora una volta che il server abbia inviato una risposta di 200 OK allo app.nocache.js.
  • Il browser tenta ancora una volta di caricare 6E89D5C912DD8F3F806083C8AA626B83.cache.html e ha esito negativo. Il browser sta ancora utilizzando la vecchia copia cache di app.nocache.js.
  • made assolutamente certo nella directory guerra che non si riferisce a 6E89D5C912DD8F3F806083C8AA626B83.cache.html (via find e grep)

cosa c'è di sbagliato? Perché il browser memorizza nella cache questo file nocache.js anche se il server lo sta inviando una nuova copia?


Ecco una copia delle intestazioni di richiesta/risposta HTTP quando si fa clic su ricarica nel browser. In questo tracciato, il contenuto del server non è stato ricompilato dall'ultimo GET (ma si noti che la versione in cache di nocache.js è ancora sbagliata!):

Request URL:http://192.168.2.4/xbts_ui/xbts_ui.nocache.js 
Request Method:GET 
Status Code:304 Not Modified 
Request Headersview source 
Accept:*/* 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8 
Cache-Control:max-age=0 
Connection:keep-alive 
Host:192.168.2.4 
If-Modified-Since:Thu, 25 Oct 2012 17:55:26 GMT 
If-None-Match:"2881105249" 
Referer:http://192.168.2.4/XBTS_ui.html 
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4 
Response Headersview source 
Accept-Ranges:bytes 
Content-Type:text/javascript 
Date:Thu, 25 Oct 2012 20:27:55 GMT 
ETag:"2881105249" 
Last-Modified:Thu, 25 Oct 2012 17:55:26 GMT 
Server:lighttpd/1.4.31 
+0

BTW, questo sembra simile a http://stackoverflow.com/questions/3407649/stop-browser-scripts-caching-in-gwt-app ma non contiene alcuna informazione che mi ha aiutato a risolvere questo problema. – jfritz42

+0

Hai letto https://developers.google.com/web-toolkit/doc/latest/DevGuideCompilingAndDebugging#perfect_caching? –

+0

Sì, e sembra che stia succedendo la cosa giusta, perché quella pagina dice "un recupero di If-Modified-Since è sufficiente". Posso sapere dallo strumento Chrome Inspect Element che il browser ha inviato "If-Modified-Since: Thu, 25 Oct 2012 17:03:53 GMT" nella richiesta GET e il server ha risposto con "Last-Modified: Thu, 25 Ott 2012 17:55:26 GMT " – jfritz42

risposta

5

Il modo migliore per evitare la memorizzazione nella cache del browser è impostare la data di scadenza a ora e aggiungere la max-age = 0 ei controlli must-revalidate.

Questa è la configurazione che uso con apache-httpd

ExpiresActive on 
<LocationMatch "nocache"> 
    ExpiresDefault "now" 
    Header set Cache-Control "public, max-age=0, must-revalidate" 
</LocationMatch> 
<LocationMatch "\.cache\."> 
    ExpiresDefault "now plus 1 year" 
</LocationMatch> 

la configurazione per LightHTTPD dovrebbe essere

server.modules = (
    "mod_expire", 
    "mod_setenv", 
) 
... 
$HTTP["url"] =~ "\.nocache\." { 
    setenv.add-response-header = ("Cache-Control" => "public, max-age=0, must-revalidate") 
    expire.url = ("" => "access plus 0 days") 
} 

$HTTP["url"] =~ "\.cache\." { 
    expire.url = ("" => "access plus 1 years") 
} 
+0

Grazie. Ho corretto alcuni refusi nella configurazione di lighttpd. Grazie per aver tradotto la configurazione di Apache in lighttpd. – jfritz42

2
  • I app.nocache.js sul browser ERA RICARICATO dal server web (200 OK), perché il file sul server era più recente della cache del browser. Ho verificato che la dimensione del file e il timestamp per il nuovo file restituito dal server fossero corretti.(Questo è informazioni Chrome riporta sulla risposta HTTP del server)

non vorrei fare affidamento su questo. Ho visto un po 'di strano comportamento negli strumenti di sviluppo di Chrome con la scheda di rete in combinazione con il caching (almeno, per me non è trasparente al 100%). In caso di dubbio, di solito continuo a consultare Firebug.

Probabilmente Chrome utilizza ancora la versione precedente. Potrebbe aver deciso molto tempo fa, che non dovrà mai più ricaricare la risorsa. Cancellare la cache dovrebbe risolvere questo. E quindi assicurati di impostare le intestazioni di cache corrette prima di ricaricare la pagina, vedi ad es. Ideal HTTP cache control headers for different types of resources.

3

Ci sono due soluzioni semplici (seconda versione è modificata del primo però)

1) Rinominare il file * .html che ha un riferimento a * .nocache.js per esempio MyProject.html a MyProject.jsp Ora ricerca la posizione di voi * .nocache.js script nella MyProject.html

<script language="javascript" src="MyProject/MyProject.nocache.js"></script> 

aggiungere una variabile dinamica come parametro per il file JS, Questo farà in modo contenuto effettivo vengono restituiti dal server ogni volta. Di seguito è esempio

<script language="javascript" src="MyProject/MyProject.nocache.jsp?dummyParam=<%= "" + new java.util.Date().getTime() %>"></script> 

Spiegazione: dummyParam sarà di alcuna utilità, ma impara a noi i nostri risultati attesi IE noi restituire 200 codice invece di 304

Nota: Se si intende utilizzare questa tecnica allora si avrà bisogno per assicurarti di indicare il file jsp corretto per caricare la tua applicazione (prima di questa modifica hai caricato la tua app usando il file HTML).

2) Se non si desidera utilizzare la soluzione JSP e si desidera attenersi al file html, sarà necessario che lo script java aggiunga dinamicamente il valore del parametro univoco sul lato client durante il caricamento del file nocache. Sto assumendo che non dovrebbe essere un grosso problema ora per te data la soluzione di cui sopra.

Ho usato la prima tecnica con successo, spero che questo possa essere d'aiuto.

-1

Dopo aver evitato di memorizzare nella cache tramite Apache ho creato uno script di bash che root viene eseguito ogni minuto in un processo cron sul mio server Linux Tomcat.

#!/bin/bash 
# 
# Touches GWT nocache.js files in the Tomcat web app directory to prevent caching. 
# Execute this script every minute in a root cron job. 
# 
cd /var/lib/tomcat7/webapps 
find . -name '*nocache.js' | while read file; do 
    logger "Touching file '$file'" 
    touch "$file" 
done 
+0

Utilizzare uno script di root per toccare un file servito dal proprio server Web è davvero una cattiva idea - esp. poiché ciò che dovresti fare, è garantire che il contenuto sia fornito con le intestazioni HTTP appropriate (il tuo server non verrà nemmeno chiesto, se il browser - o un proxy intermedio - ha memorizzato in cache il contenuto in buona fede). – R4zorax

5

Abbiamo avuto un problema simile. Abbiamo scoperto che il timestamp di nocache.js non è stato aggiornato con la compilazione di gwt, quindi è stato necessario toccare il file su build. E poi abbiamo anche applicato la correzione da @Manolo Carrasco Moñino. Ho scritto un blog su questo problema. http://programtalk.com/java/gwt-nocachejs-cached-by-browser/

Si sta utilizzando la versione 2.7 di GWT come indicato anche nel commento.

+1

Il timestamp che non cambiava era il nostro problema. Credo che sia solo un bug in GWT 2.7. Grazie per il post sul blog! – Craigo

+0

Ottima risposta. Ora ho imparato che Shift + F5 è una soluzione temporanea per la prima volta. – Tom

0

Apre la pagina in modalità cognito solo per sbarazzarsi del problema della cache e sbloccarsi.

È necessario configurare il tempo di cache come indicato in altri commenti.

Problemi correlati