2013-02-19 11 views
22

Abilitando la modalità HTML5 in AngularJS, il servizio $location riscrive gli URL per rimuovere l'hashbang da essi. Questa è una grande funzionalità che mi aiuterà con la mia applicazione, ma c'è un problema con il suo fallback alla modalità hashbang. Il mio servizio richiede l'autenticazione e sono costretto a utilizzare un meccanismo di autenticazione esterno dalla mia applicazione. Se un utente tenta di accedere a un URL per la mia app con un hashbang in esso, per prima cosa lo reindirizzerà alla pagina di autenticazione (non toccherà mai il mio servizio se non è stato autenticato con successo), quindi li reindirizzerà alla mia applicazione. Essendo che il tag hash è visto solo dal lato del client, verrà rilasciato qualsiasi parte dei percorsi dopo il momento in cui hanno colpito il mio server. Una volta che sono autenticati, potrebbero reinserire l'URL e funzionerà, ma è la prima volta che causerà un'interruzione all'esperienza utente.AngularJS La modalità HTML5 degrada fino a ricaricare la pagina intera invece di hashbang

La mia domanda è, allora, esiste un modo per andare da $location.html5Mode(true) al ripiego di ricariche a piena pagina per i browser non-solidale, saltando il metodo hashbang di instradamento interamente in AngularJS?

Il miglior confronto tra le implementazioni disponibili di ciò a cui sto mirando potrebbe essere qualcosa come sfogliare le cartelle su github.com. Se il browser supporta la riscrittura dell'URL senza avviare un aggiornamento della pagina, la pagina caricherà in modo asincrono le parti necessarie. Se il browser non lo supporta, quando un utente fa clic su una cartella, si verifica un aggiornamento a pagina intera. Questo può essere ottenuto con AngularJS invece di usare la modalità hashbang?

+1

Hai mai trovare una soluzione a questo? Sto affrontando una situazione simile. – Jonathan

risposta

1

Cercate di avvolgere $ posizione e la configurazione routeProvider $ in controllo API HTML5 Storia del browser, in questo modo:

if (isBrowserSupportsHistoryAPI()) { 
    $location.html5Mode(true) 
    $routeProvider.when(...); 
} 

può anche essere è necessario creare un involucro a $ posizione se lo si utilizza per modificare il percorso. (Scusate per l'inglese terribile)

1

Perché non gestire il reindirizzamento non autenticato sul lato client per questa situazione? Avrei bisogno di conoscere un po 'di più su esattamente come il vostro applicazione funziona per darvi una soluzione più specifica, ma essenzialmente qualcosa come:

  1. utente va a un percorso gestito da AngularJS, il server serve il modello principale e AngularJS javascript
  2. utente non è autenticato, AngularJS rileva e reindirizza alla pagina di autenticazione

si potrebbe avere qualcosa in blocco corsa del modulo per all'avvio dell'applicazione AngularJS:

module('app',[]) 
    .configure(...yadda...yadda...yadda...) 
    .run(['$location', 'authenticationService', function($location, auth) { 
    if (!auth.isAuthenticated()) { 
     $location.url(authenticationUrl) 
    } 
    }); 

Ho effettuato il sottotitolo in un servizio che consente di scoprire se si è autenticati in qualche modo, fino a che punto, potrebbe essere il controllo di un cookie di sessione, potrebbe colpire l'API per chiedere. Dipende davvero da come si desidera continuare a controllare l'autenticazione mentre l'applicazione client viene eseguita.

1

È possibile provare e sovrascrivere la funzionalità del servizio $ location. L'idea generale sarebbe quella di riscrivere l'URL in base al fatto se qualcuno è già autenticato o no, o semplicemente utilizzare un singolo approccio (senza hashbang) per tutti gli URL, indipendentemente dal fatto che html5mode sia attivo o meno.

Non sono sicuro di comprendere appieno il caso d'uso, quindi non posso scrivere il codice esatto di cui avete bisogno.Ecco un esempio di implementazione di come prevale/implementa e registra il servizio di localizzazione $, basta fare in modo che sia hashbang sempre eliminati:

app.service('$location', [function() { 
    var DEFAULT_PORTS = { 
     ftp: 21, 
     http: 80, 
     https: 443 
    }; 

    angular.extend(this, { 
     absUrl: function() { 
      return location.href; 
     }, 
     hash: function(hash) { 
      return location.hash.substr(1); 
     }, 
     host: function() { 
      return location.host; 
     }, 
     path: function(path) { 
      if (!path) { 
       return location.pathname; 
      } 
      location.pathname = path; 
      return this; 
     }, 
     port: function() { 
      return location.port ? Number(location.port) : DEFAULT_PORTS[this.protocol()] || null; 
     }, 
     protocol: function() { 
      return location.protocol.substr(0, location.protocol.length - 1); 
     }, 
     replace: function() { 
      return this; 
     }, 
     search: function(search, paramValue) { 
      if (search || paramValue) { 
       return this; 
      } 
      var query = {}; 
      location.search.substr(1).split("&").forEach(function(pair) { 
       pair = pair.split("="); query[pair[0]] = decodeURIComponent(pair[1]); 
      }); 
      return query; 
     }, 
     url: function(url, replace) { 
      return this.path(); 
     } 
    }); 
}]); 
2

non sovrascrivere le funzionalità di base.

Utilizzare Modernizr, eseguire il rilevamento delle funzioni, quindi procedere di conseguenza.

di controllo per la storia supporto API

if (Modernizr.history) { 
    // history management works! 
} else { 
    // no history support :(
    // fall back to a scripted solution like History.js 
} 
Problemi correlati