2014-04-14 26 views
21

oggi una domanda è stata sollevata qui e non ho una risposta evidente.Rileva modifica versione applicazione su un'applicazione singola pagina

Supponiamo di concatenare e minimizzare tutti i file di risorse (CSS e Javascript) e dichiararli nella "Pagina principale".

In un'applicazione multipagina, se un file CSS viene modificato, verrà ricaricato al successivo caricamento di una pagina intera.

In un'applicazione a pagina singola, l'utente può continuare a lavorare per giorni senza mai ricaricare la pagina principale in cui vengono dichiarati i file CSS. L'utente non vedrà mai le modifiche finché non viene emesso un Ctrl-F5.

sono sicuro che qualcuno ha già pensato a questo e hanno un'esperienza da condividere :)

Per me, utilizzando WebSockets non è un'opzione. Innanzitutto perché è eccessivo e in secondo luogo perché non tutti i miei clienti supportano la tecnologia. La stessa ragione si applica a tutti i fallback WebSockets ... Non continuerò a colpire i miei server a causa di questo.

Quindi, qualche idea a qualcuno? :)

BTW, stiamo usando AngularJS se questo può essere d'aiuto per una soluzione specifica.

Grazie!

risposta

21

Ho superato lo stesso problema. La mia soluzione è opinata e potrebbe non rispondere ai tuoi criteri:

Quando impacco la mia app frontale e la mia server-app, condivido un file di configurazione contenente la versione corrente dell'app anteriore.

Lato anteriore: il 75% delle mie route cambia implicitamente un servizio Web (risoluzione della modifica dell'itinerario). SO ogni volta che chiamo il mio server, includo un'intestazione HTTP personalizzata (o un parametro GET/POST) contenente la versione client dell'app anteriore.

lato

Server: metto a confronto la versione anteriore-app (quello nel browser dell'utente, caricato l'ultima volta che l'utente aggiornata/caricato lo SPA) con la versione anteriore-app del file di configurazione comune:

  • Se la versione corrisponde: I Do nothing.
  • Se la versione non corrispondono mando un codice di errore HTTP di stato personalizzato (418 per esempio)

lato Poi anteriore: ho aggiunto un intercettore risposta che intercetta qualsiasi codice di errore 418 e fare una forza-refresh di l'intera app

Questo è tutto. Fondamentalmente l'evento che "verifica" se la versione di app anteriore è l'ultima è un cambio di rotta (che chiama un WS tramite ajax). Ma potresti aggiungere un infinito $ timeout callind un WS dedicato ogni 5 minuti o così ... Posso aggiungere del codice se necessario.

Spero che questo aiuti;)

+0

La mia idea iniziale era di fare il contrario, fare in modo che il back-end inviasse la versione e facesse il confronto sul client ma c'è un problema comune in entrambi gli approcci: ho più servizi RESTful ognuno con versioni indipendenti e non so nulla di un'app specifica, in modo che non possano mai convalidarlo. Althogh, mentre sto scrivendo, sto pensando che forse il proxy inverso, che è specifico dell'applicazione, potrebbe fare il lavoro ... – AlexCode

+0

infinito timeout $ si traduce in WebSockets o le sue fallback in particolare Longpolling che non voglio usare per questo. Questo non è abbastanza spesso da giustificare continuamente il server per la verifica. – AlexCode

+0

Sì, la scelta qui dipende dalla tua intera architettura tecnica .. Se i websocket sono eccessivi e troppo recenti, puoi dare un'occhiata a SSE (eventi inviati dal server: http://www.w3schools.com/html/html5_serversentevents. asp) che sono molto più leggeri di quella presa.io per esempio (è server uni-directionnal-> client push) –

-3

Chiamami vecchio stile ma lascerò solo che il mio utente sappia che c'è un'interfaccia utente aggiornata più interessante, più bella e più interessante con qualche finestra di avviso, e quando agiscono e fanno clic su di esso - basta aggiornare il pagina. Forse il codice non risolverà questo, ma qualche psicologia UX ...

+1

La notifica va bene per me, ma come fa l'applicazione a sapere che c'è qualcosa di nuovo da aggiornare? È una SPA, dopo il primo blocco di risorse il resto del traffico è principalmente dati attraverso richieste AJAX ai servizi RESTful. – AlexCode

+0

Ah capisco .. Ho appena letto @Bixi rispondi qui e, il modo in cui mi suggerisce sembra abbastanza buono per me. Non solo per risolvere questo problema che stai affrontando ora ma per prevenire futuri mal di testa e per quanto riguarda le compatibilità della versione. – Tiwaz89

+0

Il problema è che io uso più quel solo webservice, e nessuno di questi è specifico dell'applicazione. Nessuno di loro sa nulla sull'applicazione che stanno servendo e ognuno ha una sua versione. Ho bisogno di convalidare questo nel contesto dell'applicazione, non nei servizi ... – AlexCode

1

Supponendo che si sta utilizzando il routing AngularJS' tramite il servizio $ percorso e fornitore, quindi è possibile utilizzare $routeChangeSuccess evento per eseguire una richiesta di server se ci sono cambiamenti significativi che deve essere cambiato; se ce ne sono, puoi fare una window.location.reload() per aggiornare la pagina e ottenere tutte le risorse e gli html aggiornati.

Il seguente processo può essere modificato a seconda di come si vuole implementarlo:

. Configura un file di configurazione nel tuo server indicando la versione dell'app. Puoi anche scegliere di assegnare versioni differenti per file diversi ma dato che hai concatenato tutti i tuoi file di risorse, suppongo che potresti limitare le opzioni di versione nella tua configurazione.

. Creare un servizio che contenga tutte le informazioni necessarie (versioni dei file dal server) e metodi per eseguire una richiesta server al server per verificare le versioni di file correnti memorizzate nel servizio.

. Utilizzare l'evento $routeChangeSuccess per eseguire una richiesta del server utilizzando il servizio creato nel passaggio , se la richiesta ha restituito una conferma valida della presenza di modifiche, quindi ricaricare la pagina forza tramite window.location.reload().

+0

Grazie amico. La mia ultima risposta sulla risposta di Bixi spiega cosa abbiamo fatto per ora. – AlexCode

1

ho deciso di aggiungere i miei pensieri finali come risposta anche qui:

Ci siamo andati per una soluzione ridotta per ora.

Dato che abbiamo un "servizio proxy" che è (ancora per ora) l'unico che interagisce con questa applicazione, abbiamo aggiunto la versione dell'applicazione sull'intestazione http di tutte le risposte. Se riceviamo una versione più recente, viene visualizzato un popup che notifica all'utente e viene inviato un aggiornamento completo della pagina ...

Questa soluzione non funzionerà per le applicazioni che non dispongono di un proprio servizio "privato".

Problemi correlati