2010-06-09 12 views
11

Ho una pagina che carica un sacco di immagini, css e javascript. Ho aggiunto un'intestazione Expires di gran lunga futura e ho impostato Cache-Control in pubblico su queste dipendenze esterne, quindi dovrebbero essere memorizzate nella cache. Ma ogni volta che faccio un post/reindirizza/ottieni chrome prova a caricarli di nuovo. Questo comportamento è molto simile al ricaricamento della pagina. Ho aggiunto ETags e gestito l'intestazione If-None-Match che aiuta un po ', ma genera ancora troppe richieste inutili.Ricarica pagina intera su post/reindirizzamento/ignora controllo cache

Come si comunica a chrome e safari per ottenere i file dalla cache?

chrome NOK 
safari NOK 
firefox OK 
ie  OK 

vedere anche Full page reload on Post/Redirect/Get ignoring cache control sul forum di assistenza di Google.

Chiarimento:

non voglio il browser per richiedere image1.png due volte. Dovrebbe essere memorizzato nella cache.

200 GET page1.html 
200 GET image1.png (Cache-Control: public, Expires and ETag) 
302 POST action.asp (form submitted from page1.html, redirects) 
200 GET page2.html 
304 GET image1.png (If-None-Match) 

Esempio:

ho creato un semplice esempio per illustrare il problema.

http://crydust.be/lab/prg/

intestazioni:

le intestazioni mando con l'immagine sono:

HTTP/1.1 200 OK 
Date: Fri, 18 Jun 2010 11:30:22 GMT 
Server: Apache 
Cache-Control: public, max-age=86400 
Expires: Sat, 19 Jun 2010 11:30:24 GMT 
Etag: "123" 
Content-Length: 866 
Content-Type: image/png 

che dovrebbe rendere più cache per 24 ore. Non c'è Vary: * o qualcosa del genere.

Aggiornamento: Questo comportamento è ora presente anche in Safari Mobile su iOS 4. Una regressione orribile, oltre che in termini di velocità di caricamento della pagina.

Aggiornamento: C'è una segnalazione di bug su questo problema nel webzilla bugzilla. Bug 38690 - Submitting a POST that leads to a server redirect causes all cached items to redownload

Aggiornamento: il problema persiste su iOS 4.0.1

Aggiornamento: il problema persiste su iOS 4,1

Aggiornamento: il problema persiste su iOS 4.2

Aggiornamento: il problema persiste su iOS 4.2.1 e in Chrome dalla versione 6 fino a 9.

Aggiornamento: C'è un bugreport su questo problema nel progetto Chromium.(È possibile stella a dimostrare il tuo affetto) Issue 68621: Post/Redirect/Get ignoring cache instructions

Aggiornamento: il problema persiste su Chrome dalla versione 6 fino a 10. Ora è un bug 9 mesi di età.

Aggiornamento: Il problema è stato risolto a partire dal 2011-03-21 19:33:07 PST. Ciò si riflette nel comportamento di chrome 12 (canarino).

+0

È un problema di webkit, piuttosto che un problema specifico con Chrome stesso. –

+0

@Dan, lo so, ma mi aspetto che i ragazzi di Google risolvano questo problema in una delle loro numerose versioni. C'è una patch disponibile, ma non è ancora inclusa in chrome. –

+0

Ho pensato che la patch causasse una regressione, motivo per cui non è stata accettata? –

risposta

1

Quando si F5/si aggiorna in Chrome, Safari o IE8 tutte le risorse GET vengono nuovamente richieste, anche se sono state memorizzate nella cache.

Se si guarda la richiesta/risposta con gli strumenti dev o Fiddler, il server risponde con uno stato HTTP 304 e nessun contenuto. Ciò indica al browser che non è necessario scaricarlo nuovamente e che possono continuare a utilizzare la cache.

Nella scheda delle risorse di Chrome, i file di aggiornamento aggiornati in questo modo avranno un tempo di latenza, ma un tempo di download di 0 ms.

Se si ricarica la pagina uscendo e ritornando, si scoprirà che questi file memorizzati nella cache non vengono recuperati e il server non è selezionato.

Questo comportamento di F5/refresh per la risorsa GET statica è corretto: FX e IE6 lo stanno facendo male. Aiuta anche con il comando CTRL + F5 che molti utenti non conoscono.

Non è possibile memorizzare nella cache POST o le pagine che restituiscono un reindirizzamento HTTP temporanea:

modifiche POST dei dati e dovrebbe sempre richiedere prima di essere inviati di nuovo, ei suoi risultati non vengono mai memorizzate nella cache.

I reindirizzamenti sono gestiti a un livello basso nella roba HTTP, sotto la memorizzazione nella cache. In realtà dice al browser di ottenere la risorsa da qualche altra parte e mentre può memorizzare nella cache che non ha memorizzato nella cache il reindirizzamento e deve ricontrollare.

Si dovrebbe essere in grado di memorizzare nella cache un reindirizzamento permanente 301, ma non è possibile memorizzare un reindirizzamento temporaneo 302 o 303 according to the HTTP spec.

+1

L'utente non ha premuto F5. Il browser si comporta come se F5 fosse stato premuto dopo un post/redirect/get. Non voglio mettere in cache il reindirizzamento, solo le immagini statiche. –

+0

@Kristof Neirynck - Ahh, quindi il post restituisce un reindirizzamento e la pagina esegue il ping di tutto il contenuto statico con 304, ma se ci si collega direttamente ad esso il contenuto statico viene memorizzato localmente nella cache? Sembra un insetto. Controlla le intestazioni di risposta sul contenuto statico - alcune di esse (come Vary: *) causano problemi con la cache del client in alcuni browser. Potresti trovare una soluzione alternativa lì. – Keith

0

F5 ricarica tutte le risorse della pagina in alcuni browser, in modo da ignorare le intestazioni della cache e chiedere nuovamente ogni risorsa.

Se si desidera "memorizzare" le pagine POST, è necessario convertire tali pagine in risorse statiche, ad esempio generare un file .html da .php per esempio e quindi servire l'html come risorsa statica.

Questo è valido solo se il contenuto della pagina non cambia

+0

Non sto spingendo F5. Prendo un reindirizzamento post. –

0

La correzione: cache-control: no-store

(Si consiglia inoltre di utilizzare il codice di stato 307 invece di 302, che manterrà il metodo.)

La soluzione è stata trovata, dopo molti giorni di frustrazione in un commento sul this open WebKit bug:

CachedRawResource ora mantiene la catena di reindirizzamento e ha alcune logiche banali per il controllo della correttezza, ma non è neanche lontanamente completo (controlla solo cacheControlContainsNoStore()).E ovviamente altri tipi di risorse non hanno nulla.

Problemi correlati