AngularJS: Wie lösche ich Abfrageparameter in der URL?

135

Meine AngularJS-Anwendung muss Zugriff auf das LinkedIn-Profil des Benutzers haben. Dazu muss ich den Benutzer zu einer LinkedIn-URL umleiten, die einen Rückruf-Parameter redirect_uri enthält, der LinkedIn anweist, den Benutzer zurück zu meiner Webanwendung umzuleiten und einen Abfrageparameter "Code" in die URL aufzunehmen. Es ist ein traditioneller Oauth 2.0-Flow.

Alles funktioniert einwandfrei, außer dass LinkedIn den Benutzer zurück zur folgenden URL leitet:

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

Ich möchte ?code=XXX&state=YYYaus der URL entfernen , um sie sauber zu machen. Der Benutzer muss die Abfrageparameter, die ich von LinkedIn Redirect erhalten habe, nicht sehen.

Ich habe es versucht $location.absUrl($location.path() + $location.hash()).replace(), aber es behält die Abfrageparameter in der URL.

Ich kann auch die Abfrageparameter, z. B. "Code", nicht mit extrahieren ($location.search()).code. Es scheint wie zu haben? vor # in der obigen URL wird Angular ausgetrickst.

Alecswan
quelle

Antworten:

151

ich benutze

$location.search('key', null)

Da dies meinen Schlüssel nicht nur löscht, sondern aus der Sichtbarkeit auf der URL entfernt.

Julius
quelle
2
Dies führt dazu, dass eine Zurück-Schaltflächenschleife in Chrome wie bei der Zurück-Schaltfläche zu //example.com?key=value zurückkehrt, jedoch vorwärts zu //example.com. Vorschläge?
Jaybro
2
Das klingt für mich ein bisschen nach Codeproblemen. Angular sollte nichts weiterleiten, es sei denn, Sie haben einen König der Methoden hinzugefügt. Das Hinzufügen von .replace () ersetzt außerdem den aktuellen Verlaufseintrag.
Julius
viewModelHelper.navigateTo ('foo /'); Die Abfragezeichenfolge wurde in der foo-URL beibehalten, daher habe ich sie mithilfe von window.location.href = 'foo /' behoben. stattdessen.
Jaybro
2
Verwenden Sie kein Fenster, sondern stattdessen Angulars $ -Fenster. Der Unit-Test wird einfacher. Mehr: docs.angularjs.org/api/ng/service/$window
Julius
Diese Antwort funktioniert perfekt, wenn Sie einen bestimmten Parameter löschen möchten, danke.
Dexxo
107

Am Ende bekam ich die Antwort vom AngularJS-Forum. Siehe diesen Thread für Details


Der Link führt zu einem Google Groups-Thread, der schwer zu lesen ist und keine klare Antwort liefert. Verwenden Sie zum Entfernen von URL-Parametern

$location.url($location.path());
Alecswan
quelle
Ich denke, Sie wollten den Pfad in $ location.url () anstelle von $ location.path einfügen. Der Versuch, beide wie oben zusammenzuführen, funktioniert bei mir nicht.
mbdev
1
funktioniert auch bei mir nicht. Beide Funktionen belassen den Abfrageparameter dort.
Pablo Ezequiel Leone
hilfreiche Antwort in der Tat. In meinem Szenario wurden jedes Mal nach dem ersten Auslösen von $ location.path ('/ reportmaint'). Search ({<myparams>}) die vorherigen Abfrageparameter nie gelöscht.
Bob.mazzo
Dies führt dazu, dass eine Zurück-Schaltflächenschleife in Chrome wie bei der Zurück-Schaltfläche zu //example.com?key=value zurückkehrt, jedoch vorwärts zu //example.com. Vorschläge?
Jaybro
+1 fürThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Vlad
70

Gehen Sie folgendermaßen vor, um ALLE Abfrageparameter zu entfernen :

$location.search({});

Gehen Sie folgendermaßen vor, um EINEN bestimmten Abfrageparameter zu entfernen :

$location.search('myQueryParam', null);
Rahul Desai
quelle
2
Funktioniert auch für Angular 1.5.
Manish M Demblani
1
funktioniert auch mit undefined, falls Sie vermeiden, nullwie ich zu verwenden.
HankScorpio
Was ich nicht mag, ist, wenn Sie mit der Zurück-Schaltfläche des Browsers zurückkehren, verlieren Sie die Suchabfrage, die ich gerade zuvor auf meiner vorherigen Suchseite durchgeführt habe.
Gino
@Gino Als Workaround können Sie dem Browserverlauf vor diesem Zurücksetzen einen Datensatz hinzufügen. stackoverflow.com/q/10541388/586051
Rahul Desai
@ RahulDesai Ich benutze ng-route, ich hart es wird es automatisch tun
Gino
29

Um ein Element zu löschen, löschen Sie es und rufen Sie $$ compose auf

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

abgeleitet von anglejs Quelle: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443

Basarat
quelle
2
brillant! Lief wie am Schnürchen.
Paulcpederson
Das hat bei mir funktioniert, aber ich würde annehmen, dass Julius 'Lösung korrekter ist, da es anscheinend das ist, was Angular-Jungs bei der Erstellung der searchMethode im Sinn hatten . docs.angularjs.org/api/ng/service/$location#search
zmilojko
1
Danke, das hat ganz gut funktioniert ... Interessanterweise setzt / komponiert IE8 diese URL gerne und lädt sie anschließend. Ich bin mir sicher, dass dies der Grund ist, warum korrektes Routing bevorzugt wird und warum wir alle schlechte Menschen sind. : P
Romanulus
27

Sie können einen bestimmten Abfrageparameter löschen, indem Sie Folgendes verwenden:

delete $location.$$search.nameOfParameter;

Oder Sie können alle Abfrageparameter löschen, indem Sie die Suche auf ein leeres Objekt setzen:

$location.$$search = {};
Quintin
quelle
2
Ich weiß nicht warum, aber diese Lösung funktioniert beim Umschalten von Seiten nicht gut (die Parameter können wieder angezeigt werden, selbst wenn sie $location.$$search = {}ausgeführt werden). @ basarat Lösung funktioniert gut.
Mik378
1
Hat bei mir gut funktioniert - überprüfen Sie vielleicht die Reihenfolge, in der Sie den Parameter entfernen und den Pfad ändern?
Demaniak
1
Obwohl dies möglicherweise funktioniert, greift es auf private Variablen zu, die nicht geändert werden sollten, siehe @ Julius Antwort für eine andere Lösung
Ben Taliadoros
26

Zum Zeitpunkt des Schreibens und wie bereits von @Bosh erwähnt, html5modemuss sein true, um einstellen zu können$location.search() und wieder in die visuelle URL des Fensters übernommen werden kann.

Weitere Informationen finden Sie unter https://github.com/angular/angular.js/issues/1521 .

Aber wenn html5mode isttrue Sie leicht die Query - String - URL löschen können:

$location.search('');

oder

$location.search({});

Dadurch wird auch die visuelle URL des Fensters geändert.

(Getestet in AngularJS Version 1.3.0-rc.1mit html5Mode(true).)

Fredric
quelle
12

Müssen Sie es funktionieren lassen, wenn html5mode= false?

Alle anderen Antworten funktionieren nur, wenn Angulars html5modeist true. Wenn Sie außerhalb von arbeiten html5mode, $locationbezieht sich dies nur auf den "falschen" Ort, der in Ihrem Hash lebt - und so weiter$location.search kann daher die Suchparameter der eigentlichen Seite nicht sehen / bearbeiten / korrigieren.

Hier ist eine Behelfslösung im HTML - Code der Seite eingefügt werden , bevor Winkel Lasten:

<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>
Bosh
quelle
2
Eine andere Möglichkeit, die Konfiguration von html5Mode auf true zu vermeiden, besteht darin, die Abfragezeichenfolge so zu erstellen, dass sie das # direkt vor dem ? Enthält . . so haben myapp/#?client=clientName statt myapp/?client=clientName
Angel Gao
5

Benutz einfach

$location.url();

Anstatt

$location.path();
Kevinius
quelle
4

Wenn Sie zu einer anderen URL wechseln und die Abfrageparameter löschen möchten, verwenden Sie einfach:

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

Wenn Sie Routenparameter verwenden, löschen Sie einfach $ routeParams

$routeParams= null;
Oswaldo Alvarez
quelle
1
Dadurch wird nur die lokale Variable $routeParamsauf gesetzt null. Beeinflusst die URL-Parameter in der Adressleiste überhaupt nicht.
Eric F.
1

Wie wäre es, wenn Sie nur den Standort-Hash auf null setzen

$location.hash(null);
Bwyss
quelle
0

Wenn Sie die Parameter sofort verarbeiten und dann zur nächsten Seite wechseln, können Sie am Ende der neuen Position ein Fragezeichen setzen.

Zum Beispiel, wenn Sie $ location.path ('/ nextPage') ausgeführt hätten.

Sie können dies stattdessen tun: $ location.path ('/ nextPage?');

user5487176
quelle
0

Ich habe die obigen Antworten ausprobiert, konnte sie aber nicht zum Laufen bringen. Der einzige Code, der für mich funktionierte, war$window.location.search = ''

Gwen Au
quelle
0

Ich kann alle Abfrageparameter durch diese einzelne Zeile ersetzen: $location.search({});
Einfach zu verstehen und einfach zu löschen.

Lucas Reppe Welander
quelle
0

Die akzeptierte Antwort funktionierte für mich, aber ich musste etwas tiefer graben, um die Probleme mit dem Zurück-Knopf zu beheben.

Was mir aufgefallen ist, ist, dass ich, wenn ich mit auf eine Seite verlinke <a ui-sref="page({x: 1})">und dann die Abfragezeichenfolge mit entferne $location.search('x', null), keinen zusätzlichen Eintrag in meinem Browserverlauf erhalte, sodass ich mit der Schaltfläche "Zurück" dorthin zurückkehre, wo ich angefangen habe. Obwohl ich der Meinung bin, dass dies falsch ist, weil ich nicht denke, dass Angular diesen Verlaufseintrag automatisch für mich entfernen sollte, ist dies tatsächlich das gewünschte Verhalten für meinen speziellen Anwendungsfall.

Das Problem ist, dass ich, wenn ich <a href="https://stackoverflow.com/page/?x=1">stattdessen mit auf die Seite verlinke und dann die Abfragezeichenfolge auf die gleiche Weise entferne , einen zusätzlichen Eintrag in meinem Browserverlauf erhalte, sodass ich zweimal auf die Schaltfläche "Zurück" klicken muss, um zu meinem Ausgangspunkt zurückzukehren . Dies ist ein inkonsistentes Verhalten, aber tatsächlich scheint dies korrekter zu sein.

Ich kann das Problem mit hrefLinks leicht beheben, indem ich benutze $location.search('x', null).replace(), aber dies bricht die Seite, wenn Sie über einen ui-srefLink darauf landen , so dass dies nicht gut ist.

Nach langem Herumspielen ist dies die Lösung, die ich mir ausgedacht habe:

In der runFunktion meiner App habe ich Folgendes hinzugefügt:

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

Dann benutze ich diesen Code, um den Parameter der Abfragezeichenfolge zu entfernen:

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

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

Für Angular> 2 können Sie allen Parametern, die Sie löschen möchten, null übergeben

this.router.navigate(['/yourRoute'], {queryParams:{params1: null, param2: null}})
Fateh Mohamed
quelle