Intestazioni per prevenire richieste 304 / Se modificate dal momento che HEAD


31

Quali intestazioni dovrei inviare per interrompere completamente tutte le richieste al server dopo che il contenuto è stato memorizzato nella cache?

Abbiamo un server a latenza molto alta (Sigh, VMWare), quindi anche l'invio di una HEADrichiesta al server richiede + 40ms.

Attualmente queste sono le intestazioni inviate / ricevute;

Prima richiesta

Il cliente invia;

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache

Il server risponde;

HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000

Quindi invia a Cache-Controle Expiresheader impostato a 365 giorni in futuro. Sfortunatamente al secondo aggiornamento richiede nuovamente l'oggetto con If-Modified-Sinceun'intestazione.

Seconda richiesta

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0

Risposta;

HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000

Sfortunatamente a causa di software proxy stupidamente obsoleto che non possiamo usare Keep-Aliveo mettere altri server / proxy davanti all'applicazione. Inoltre, non possiamo migliorare le prestazioni del server e ridurre la latenza della rete. Ho cercato di capire quali intestazioni possiamo inviare per sbarazzarci delle 301 richieste. Ho provato a usare ETags ma questo non fa differenza, invia comunque If-modified-sinceun'intestazione. Ho anche provato a rimuovere l' Last-Modifiedintestazione, ma ciò causa solo una richiesta GET standard senza memorizzazione nella cache (controllati i registri, il server continua a ricevere richieste).

I client sono un mix di Firefox (principalmente), IE 7, 8 e (alcuni) 9, Chrome e Safari, ma questo comportamento sembra comparire in tutti i browser testati.

TL; DR;

Rete terribile, quali intestazioni dovrei inviare per dire ai clienti di non inviare mai maiIf-modified-since richieste al server per convalidare la loro cache e mantenere il contenuto nella cache fino a quando non Expiresviene soddisfatta l' intestazione?

Probabilmente mi manca qualcosa di ovvio, ma tutto ciò che provo sembra produrre gli stessi risultati.

Abbiamo un server NGINX posizionato di fronte al nostro server delle applicazioni in modo da poter aggiungere / rimuovere qualsiasi intestazione come mi pare. Il nostro proxy non supporta Keep-Alive e non è in alcun modo possibile migliorare le prestazioni della rete. A causa del terribile design del software, l'app Web carica +100 risorse per ogni caricamento della pagina (Sì, il software aziendale fa schifo) con una latenza di ~ 40-50ms per oggetto.


1
Hmm, è strano. L'invio delle intestazioni Scadenza e Massima età dovrebbe impedire ulteriori richieste dell'immagine. Modifica: a proposito, qual è il problema con l'invio di un JPG come text/plain?
DisgruntledGoat

1
@DisgruntledGoat Ahh, hai supposto che un file .jpg sia in realtà un'immagine piuttosto che un documento di testo. Benvenuto nel mio mondo =) (In realtà è un file di testo che contiene 'Hello World' per i miei test, il software rinomina tutti i file in sequenza IMG_xxxx.jpg indipendentemente dal tipo. Cool eh?)
Sfumino

cosa stavi usando per impostare le intestazioni delle richieste http?
barlop

Risposte:


25

Non puoi davvero controllare quali intestazioni gli user agent decidono di inviarti. Se il file in questione si trova nella cache del browser e decide che è necessario controllare una nuova versione, lo farà. Secondo questo articolo , queste sono le situazioni che i browser richiederanno utilizzando If-Modified-Since:

  • La voce memorizzata nella cache non ha una data di scadenza e si accede al contenuto per la prima volta in una sessione del browser
  • La voce memorizzata nella cache ha una data di scadenza ma è scaduta
  • L'utente ha richiesto un aggiornamento della pagina facendo clic sul pulsante Aggiorna o premendo F5

Quindi, se si sta ricaricando la pagina per testare la memorizzazione nella cache, non funzionerà poiché il browser richiederà nuovamente le immagini. Prova a fare clic su un collegamento, quindi su un altro collegamento alla prima pagina. Se i tuoi utenti ricaricano regolarmente le pagine, potrebbe essere necessario ripensare la struttura del tuo sito / app per evitarlo.

Una cosa che può aiutare è l'aggiunta di "pubblico" all'intestazione del controllo cache, ad es Cache-Control: public, max-age=31536000. Di recente ho anche appreso che una data di scadenza superiore a un anno non è valida. Poiché la data di scadenza è esattamente un anno, forse abbassandolo di qualche giorno o settimana si assicurerebbe che il file rimanga nella cache del browser e non venga scartato.


Interessante, abbasserò la scadenza a 60 giorni e aggiungerò la bandiera pubblica e vedrò cosa succede. Ciò sembrava accadere sui clic sui collegamenti anziché sugli F5 (secondo Firebug e i registri del server)
Smudge,

Tecnicamente, la specifica HTTP / 1.1 dice solo che "i server NON DOVREBBERO spedire le date di scadenza più di un anno in futuro" (presumibilmente perché è un tempo ridicolmente lungo prima della scadenza) e che "circa un anno" in futuro è la scadenza appropriata tempo di invio per contenuti che non dovrebbero mai scadere.
Ilmari Karonen,

1
Dopo aver giocato un po ', ho concluso che la scadenza di 365 giorni non sta influenzando i nostri clienti, ma l'ho lasciato cadere per sicurezza, sembra che sia Cache-Control: public,...stata la chiave di questa situazione specifica.
Sfuma il

Vuoi dire che l'intestazione "pubblica" ha risolto i round trip inutili? L'ho provato, ma senza successo ...
phtrivier,

2
Nel caso non fosse chiaro dalla mia risposta, ricaricare la pagina nel tuo browser richiederà nuovamente i file . Basta fare clic sui collegamenti per aprire le pagine e il browser utilizza la sua cache.
DisgruntledGoat


3

Ho avuto lo stesso problema e le Richieste stanno sicuramente colpendo il server affinché risponda con lo 304stato - Sto inviando il 304 tramite un C # e sicuramente colpisce il server ..

Avevo solo Cache-Control: privateimpostato. No max-agee no ExpiresOperava come previsto; colpire il server con il punto in If-Modified-Sincecui collaudo il valore rispetto a quello che mi aspetto e fornire 304w / corpo di risposta vuoto - altrimenti 200e pieno il corpo di risposta.

L'impostazione Expiresdell'intestazione ha prodotto i risultati desiderati, 200 - (from cache)sul client e nessuna richiesta HTTP ha colpito il server.

Ma .. Ho scoperto che l'impostazione SIA max-age= e Expirespuò impedire ai browser di inviare l' If-Modified-Sinceintestazione E di non memorizzare nella cache se i valori non corrispondono .

Qualcosa da tenere presente se si hanno problemi di memorizzazione nella cache e si utilizzano le diverse intestazioni in combinazione.


1

Un po 'fuori tema ma forse utile. Un altro miglioramento per le tue richieste di contenuti memorizzati nella cache è la memorizzazione nella cache di sessionStorage in modo da non dover chiedere al server di convalidare la cache e ricevere un 304. Cerca ad esempio google, apri la console e scrivi sessionStorage. Vedrai che stanno memorizzando nella cache CSS o DOM con sessionStorage. ofc, non puoi usarlo nei vecchi browser IE.


0

Controlla il tuo codice sorgente e assicurati che non ci siano META REFRESH per passare a un'altra pagina. Usa invece qualcosa come sendRedirect. Nella mia configurazione, META REFRESH produce 304 in IE, ma non Chrome. sendRedirect non produce questo su nessuno dei due browser.

<meta http-equiv="refresh" content="0;URL='nextpage'" />    

vs

<% response.sendRedirect("nextpage") %>
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.