AngularJS: come cancellare i parametri di query nell'URL?


135

La mia applicazione AngularJS deve avere accesso al profilo LinkedIn dell'utente. Per fare ciò devo reindirizzare l'utente a un URL di LinkedIn che contiene un parametro redirect_uri di callback che dirà a LinkedIn di reindirizzare l'utente al mio webapp e includere un parametro di query "codice" nell'URL. È un flusso Oauth 2.0 tradizionale.

Tutto funziona alla grande, tranne che LinkedIn reindirizza l'utente al seguente URL:

http://localhost:8080/?code=XXX&state=YYY#/users/123/providers/LinkedIn/social-sites

Vorrei rimuovere ?code=XXX&state=YYYdall'URL per renderlo pulito. Non è necessario che l'utente visualizzi i parametri della query che ho ricevuto dal reindirizzamento di LinkedIn.

Ho provato $location.absUrl($location.path() + $location.hash()).replace(), ma mantiene i parametri della query nell'URL.

Inoltre, non sono in grado di estrarre i parametri della query, ad es. "Codice" ($location.search()).code. Sembra di averlo? prima che # nell'URL sopra stia ingannando Angular.

Risposte:


151

Io uso

$location.search('key', null)

Poiché questo non solo elimina la mia chiave, ma la rimuove dalla visibilità sull'URL.


2
ciò provoca un loop del pulsante Indietro in Chrome, poiché nel pulsante Indietro torna a //esempio.com?key=valore, ma in avanti angolare a //esempio.com. Suggerimenti?
jaybro,

2
Questo suona un po 'come il problema del codice per me. Angular non dovrebbe inoltrare nulla, a meno che non ci sia qualche re di metodo aggiunto da te. Inoltre, l'aggiunta di .replace () sostituisce la voce della cronologia corrente.
Giulio

viewModelHelper.navigateTo ( 'foo /'); stava persistendo la stringa di query nell'URL foo, quindi l'ho risolto usando window.location.href = 'foo /'; anziché.
jaybro,

2
Non usare la finestra, usa invece la finestra $ di Angular. Sarà più semplice test unitario. Altro: docs.angularjs.org/api/ng/service/$window
Julius

Questa risposta funziona perfettamente se si desidera eliminare un parametro specifico, grazie.
Dexxo,

107

Ho finito per ottenere la risposta dal forum AngularJS. Vedi questa discussione per i dettagli


Il link è a un thread di Google Gruppi, che è difficile da leggere e non fornisce una risposta chiara. Per rimuovere i parametri URL utilizzare

$location.url($location.path());

Penso che intendevi mettere il percorso in $ location.url () invece di $ location.path. Cercare di unirli entrambi come sopra non funziona per me.
mbdev,

1
non funziona anche per me. Entrambe le funzioni lasciano il parametro query lì.
Pablo Ezequiel Leone,

risposta utile davvero. Nel mio scenario, ogni volta dopo la prima volta che ho attivato $ location.path ('/ reportmaint'). Search ({<myparams>}), non ha mai cancellato i parametri della query precedente.
bob.mazzo,

ciò provoca un loop del pulsante Indietro in Chrome, poiché nel pulsante Indietro torna a //esempio.com?key=valore, ma in avanti angolare a //esempio.com. Suggerimenti?
jaybro,

+1 perThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Vlad

70

Per rimuovere TUTTI i parametri della query, eseguire:

$location.search({});

Per rimuovere UN parametro di query particolare, eseguire:

$location.search('myQueryParam', null);

2
Funziona anche con Angular 1.5.
Manish M Demblani

1
funziona anche con undefined, nel caso in cui tu stia evitando di usare nullcome sono io.
HankScorpio,

Quello che non mi piace è che se torni indietro con il pulsante Indietro del browser, perdi la query di ricerca che ho fatto prima nella mia precedente pagina di ricerca.
Gino,

@Gino Come soluzione alternativa, è possibile aggiungere un record alla cronologia del browser prima di questo ripristino. stackoverflow.com/q/10541388/586051
Rahul Desai

@RahulDesai Sto usando ng-route, sono forte lo farà automaticamente
Gino

29

Per cancellare un elemento, cancellalo e chiama $$ compose

    if ($location.$$search.yourKey) {
        delete $location.$$search.yourKey;
        $location.$$compose();
    }

derivato dalla fonte angularjs: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443


2
brillante! Ha funzionato come un fascino.
paulcpederson,

Questo ha funzionato per me, ma suppongo che la soluzione di Julius sia più corretta, poiché sembra essere ciò che i ragazzi angolari avevano in mente quando hanno creato il searchmetodo. docs.angularjs.org/api/ng/service/$location#search
zmilojko

1
Grazie, ha funzionato abbastanza bene ... È interessante notare che a IE8 piace impostare / comporre quell'URL e caricarlo successivamente. Sono sicuro che questo è il motivo per cui è preferibile il routing corretto e anche perché siamo tutti cattivi. : P
Romanulus,

27

È possibile eliminare un parametro di query specifico utilizzando:

delete $location.$$search.nameOfParameter;

Oppure puoi cancellare tutti i parametri della query impostando la ricerca su un oggetto vuoto:

$location.$$search = {};

2
Non so perché, ma questa soluzione non funziona bene quando si passa da una pagina all'altra (i parametri possono riapparire, anche se $location.$$search = {}eseguiti). La soluzione @basarat funziona bene.
Mik378

1
Ha funzionato bene per me - forse controlla la sequenza in cui stai rimuovendo il parametro e cambiando percorso?
demaniak,

1
Anche se può funzionare, accede a variabili private che non dovrebbero essere modificate, vedi la risposta di @Julius per un'altra soluzione
Ben Taliadoros,

26

Al momento della stesura di questo documento, e come precedentemente menzionato da @Bosh, html5modedeve trueessere possibile per poterlo impostare $location.search()e farlo riflettere nell'URL visivo della finestra.

Vedi https://github.com/angular/angular.js/issues/1521 per maggiori informazioni.

Ma se html5mode ètrue possibile cancellare facilmente la stringa di query dell'URL con:

$location.search('');

o

$location.search({});

Ciò modificherà anche l'URL visivo della finestra.

(Testato nella versione AngularJS 1.3.0-rc.1con html5Mode(true).)


12

Devi farlo funzionare quando html5mode= false?

Tutte le altre risposte funzionano solo quando lo html5modeè Angular true. Se lavori al di fuori di html5mode, allora si $locationriferisce solo alla posizione "falsa" che vive nel tuo hash - e quindi $location.searchnon puoi vedere / modificare / correggere i parametri di ricerca della pagina reale.

Ecco una soluzione alternativa, da inserire nell'HTML della pagina prima dei carichi angolari:

<script>
  if (window.location.search.match("code=")){
    var newHash = "/after-auth" + window.location.search;
    if (window.history.replaceState){
      window.history.replaceState( {}, "", window.location.toString().replace(window.location.search, ""));
    }
    window.location.hash = newHash;
  }
</script>

2
Un altro modo in cui ho evitato di configurare html5Mode su true è creando la stringa di query in modo che contenga il # proprio prima del ? . così ho myapp/#?client=clientName invece myapp/?client=clientName
Angel Gao il

5

Basta usare

$location.url();

Invece di

$location.path();

4

Se vuoi passare a un altro URL e cancellare i parametri della query, utilizza semplicemente:

$location.path('/my/path').search({});

1

Se stai utilizzando i parametri di route, deseleziona $ routeParams

$routeParams= null;

1
Questo imposterà semplicemente la variabile locale $routeParamssu null. In realtà non influenzerà affatto i parametri URL nella barra degli indirizzi.
Eric F.

1

Che ne dici di impostare solo l'hash della posizione su null

$location.hash(null);

0

se si elaborano immediatamente i parametri e si passa alla pagina successiva, è possibile inserire un punto interrogativo alla fine della nuova posizione.

per esempio, se avessi fatto $ location.path ('/ nextPage');

puoi invece farlo: $ location.path ('/ nextPage?');


0

Ho provato le risposte sopra ma non sono riuscito a farle funzionare. L'unico codice che ha funzionato per me era$window.location.search = ''


0

Posso sostituire tutti i parametri della query con questa singola riga: un modo $location.search({});
facile da capire e semplice per cancellarli.


0

La risposta accettata ha funzionato per me, ma avevo bisogno di scavare un po 'più a fondo per risolvere i problemi con il pulsante Indietro.

Quello che ho notato è che se collego a una pagina utilizzando <a ui-sref="page({x: 1})">, quindi rimuovere la stringa di query utilizzando$location.search('x', null) , non ottengo una voce aggiuntiva nella cronologia del mio browser, quindi il pulsante Indietro mi riporta a dove ho iniziato. Sebbene ritenga che ciò sia sbagliato perché non credo che Angular dovrebbe rimuovere automaticamente questa voce della cronologia per me, questo è in realtà il comportamento desiderato per il mio caso d'uso specifico.

Il problema è che se mi collego alla pagina utilizzando <a href="https://stackoverflow.com/page/?x=1">, invece, quindi rimuovere la stringa di query nello stesso modo, mi faccio trovare una voce in più nel mio cronologia del browser, quindi devo fare clic sul pulsante Indietro due volte per tornare a dove ho iniziato . Questo è un comportamento incoerente, ma in realtà sembra più corretto.

Posso facilmente risolvere il problema con i hrefcollegamenti utilizzando $location.search('x', null).replace(), ma questo interrompe la pagina quando si arriva su di esso tramite un ui-srefcollegamento, quindi non va bene.

Dopo aver armeggiato molto, questa è la soluzione che mi è venuta in mente:

Nella runfunzione della mia app ho aggiunto questo:

$rootScope.$on('$locationChangeSuccess', function () {
    $rootScope.locationPath = $location.path();
});

Quindi uso questo codice per rimuovere il parametro della stringa di query:

$location.search('x', null);

if ($location.path() === $rootScope.locationPath) {
    $location.replace();
}

0

Per Angolare> 2 , è possibile passare null a tutti i parametri che si desidera cancellare

this.router.navigate(['/yourRoute'], {queryParams:{params1: null, param2: null}})
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.