2012-06-28 17 views
9

Per migliorare le prestazioni/la reattività del mio sito Web ho implementato un caricamento parziale della pagina utilizzando AJAX, replaceState, pushState e un listener popstate.Pulsante indietro dell'API cronologia HTML5 con carichi di pagina parziali

In sostanza, memorizzo la parte centrale della mia pagina (HTML) come oggetto di stato nella cronologia. Quando si fa clic su un collegamento, chiedo solo il bit centrale della pagina dal server (identificando queste richieste con un'intestazione Accept diversa) e lo sostituisco con javascript. Su popstate afferro la parte centrale precedente e la spingo indietro nel dom.

Principalmente funziona bene, tuttavia ho trovato un problema particolare su cui sono bloccato. È un po 'complicato da spiegare, quindi mi scuso se questo non è molto chiaro.

C'è un modulo di ricerca sulla maggior parte delle nostre pagine. Il caricamento parziale della pagina tramite ajax è solo su richieste GET e il modulo esegue un POST che si traduce in un caricamento di pagina completo.

Se a navigare la seguente serie di pagine, io alla fine su una pagina parziale malformati composto da SOLO il contenuto centrale, senza che nessuna delle dom circostante:

Start sulla pagina principale (via piena pagina carico) - eseguire una ricerca (post-redirect-get)
vi porta ai risultati della ricerca (attraverso pieno carico pagina) - scegliere la casa
voi di tornare alla pagina principale (via get dinamica) - clicca navigatore indietro
Ricerca Risultati (dal listener popstate) - fare clic sul browser indietro
home malformato pag e.

Quando viene visualizzata la home page non valida, il mio listener popstate non è affatto presente.

Quello che penso che stia accadendo, è che il secondo caricamento (dinamico, parziale) della home page viene memorizzato nella cache dal browser, e quindi quando si verifica il retro della pagina intera, il browser sta semplicemente mostrando il parziale memorizzato nella cache risposta piuttosto che la pagina intera.

Per provare a porre rimedio a ciò ho aggiunto un Vary: Accept intestazione alla risposta per consentire ai browser di sapere che il contenuto potrebbe cambiare in base all'intestazione di accettazione. Ho anche aggiunto Cache-Control max-age = 0, pragma no-cache e una data di scadenza passata al contenuto caricato parziale per provare a forzare il browser a non mettere in cache questo, ma nessuno di questi lo risolve.

Sfortunatamente la mia azienda non consente il traffico esterno ai nostri server di sviluppo, quindi non posso mostrarvi il problema. Ho esaminato varie domande simili qui, ma nessuna sembra essere la stessa, né le soluzioni suggerite sembrano funzionare.

Se aggiungo un parametro senza senso (blah = blah) alle mie richieste GET dinamiche, questo risolve il problema. Comunque questo è un brutto scherzo che preferirei non fare. Questo sembra che dovrebbe essere risolvibile con le intestazioni, dal momento che penso che sia un problema di cache. Qualcuno può spiegare cosa sta succedendo?

+0

Aggiornamento rapido: le intestazioni sembrano risolvere il problema su Firefox, tuttavia persistono su Chrome e iOS Safari (problema con il webkit forse?) –

+0

Sembra un problema di memorizzazione nella cache. Aggiungere un parametro alle richieste GET dinamiche sembra ragionevole - questo è ciò che fa jquery-pjax. –

risposta

8

Questo è un problema di memorizzazione nella cache. Con l'intestazione di risposta Cache-Control impostata su no-cache o max-age=0, il problema non si verifica in FF (come hai detto), ma persiste in Chrome.

L'intestazione che ha funzionato per me è Cache-Control: no-store. Ciò non viene implementato in modo coerente da tutti i browser (puoi trovare domande chiedendo qual è la differenza tra no-cache e no-store), ma ha il risultato che ti aspetti anche in Chrome.

1

Ho avuto un problema simile. Sto creando una procedura guidata basata sul Web e utilizzando jquery ajax per caricare ogni passaggio (ASP.NET MVC sul back-end).

Il percorso iniziale che è qualcosa di simile/Domande/Show - che carica l'intera pagina e visualizza la prima domanda (domanda 0). Quando l'utente fa clic sull'immagine successiva, esegue un jquery .load() con l'url/Questions/Save/0. Ciò salva la risposta e restituisce una vista parziale con la domanda successiva. Il prossimo salvataggio fa un .load jQuery() con/Domande/SAVE/1 ...

ho implementato History.js modo che l'utente può andare avanti e indietro (via?). Memorizza il numero della domanda nei dati di stato. Quando rileva un cambio di stato (e il numero di domanda dello stato è diverso da quello che c'è nella pagina), fa un jquery .load() per caricare la domanda corretta.

Inizialmente usavo lo stesso percorso di quando viene caricata la pagina iniziale (/ Domande/Mostra/X dove X è il numero della domanda). Sul back-end ho rilevato se si trattava di una richiesta Ajax, e in caso affermativo restituiva una vista parziale invece della vista completa. È qui che il problema si presentava simile al tuo: dire che ero alla domanda 3, tornò indietro, poi in avanti, poi andò su www.google.com, quindi premetti il ​​pulsante Indietro. Mostrava la domanda 3 ma era la vista parziale - perché il browser memorizzava nella cache il partial per quella rotta.

La mia soluzione era di creare un percorso separato per la chiamata ajax:/Questions/Load/X (utilizzato codice comune sul back-end). Ora con due percorsi diversi (/ Domande/Mostra per non-ajax e/Domande/Carica per ajax), il browser mostra correttamente la pagina completa nella situazione di cui sopra.

Quindi forse una soluzione simile potrebbe funzionare per voi ... cioè due percorsi diversi per la vostra home page - uno per la pagina intera e uno per un parziale. Spero possa aiutare.

0

Quando un link viene cliccato Chiedo solo la punta centrale della pagina dal server (identificare queste richieste con una diversa intestazione Accept) e sostituirlo con javascript.

Impressionante. Questo è il modo RESTful di farlo. Ma c'è ancora una cosa da fare per farlo funzionare: aggiungi un'intestazione Vary alla risposta.

Vary: Accept 

Questo indica al browser che una richiesta con un'intestazione Accept diversa può ottenere una risposta diversa. Poiché le due richieste utilizzano intestazioni Accept diverse, il browser (e tutti i proxy di memorizzazione nella cache) memorizzeranno le risposte separatamente nella cache.

A differenza dell'impostazione Cache-Control: no-store, questo consente comunque di utilizzare la memorizzazione nella cache.

Problemi correlati