AngularJS: Jak wyczyścić parametry zapytania w adresie URL?

135

Moja aplikacja AngularJS musi mieć dostęp do profilu LinkedIn użytkownika. Aby to zrobić, muszę przekierować użytkownika do adresu URL LinkedIn, który zawiera parametr redirect_uri wywołania zwrotnego, który poinformuje LinkedIn, aby przekierował użytkownika z powrotem do mojej aplikacji internetowej i zawarł parametr zapytania „kod” w adresie URL. To tradycyjny przepływ Oauth 2.0.

Wszystko działa świetnie, z wyjątkiem tego, że LinkedIn przekierowuje użytkownika z powrotem na następujący adres URL:

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

Chciałbym usunąć ?code=XXX&state=YYYz adresu URL, aby był czysty. Użytkownik nie musi widzieć parametrów zapytania, które otrzymałem z przekierowania LinkedIn.

Próbowałem $location.absUrl($location.path() + $location.hash()).replace(), ale zachowuje parametry zapytania w adresie URL.

Nie jestem również w stanie wyodrębnić parametrów zapytania, np. „Kod”, używając ($location.search()).code . Wygląda na to, że masz? przed # w powyższym adresie URL oszukuje Angulara.

alecswan
źródło

Odpowiedzi:

151

używam

$location.search('key', null)

Ponieważ to nie tylko usuwa mój klucz, ale usuwa go z widoczności pod adresem URL.

Julius
źródło
2
powoduje to pętlę przycisku Wstecz w przeglądarce Chrome, ponieważ przycisk Wstecz wraca do //example.com?key=value, ale kątowo prowadzi do //example.com. Propozycje?
jaybro
2
Brzmi to trochę jak problem z kodem. Angular nie powinien niczego przekazywać, chyba że dodasz jakiś rodzaj metody. Ponadto dodanie .replace () zastępuje bieżący wpis historii.
Julius
viewModelHelper.navigateTo ('foo /'); utrzymywał ciąg zapytania w adresie url foo, więc naprawiłem to za pomocą window.location.href = 'foo /'; zamiast.
jaybro
2
Nie używaj okna, zamiast tego użyj $ window Angulara. Test jednostkowy będzie łatwiejszy. Więcej: docs.angularjs.org/api/ng/service/$window
Julius
Te odpowiedzi działają idealnie, jeśli chcesz usunąć określony parametr, dziękuję.
Dexxo
107

W końcu otrzymałem odpowiedź z forum AngularJS. Zobacz ten wątek po szczegóły


Link prowadzi do wątku w Grupach dyskusyjnych Google, który jest trudny do odczytania i nie daje jasnej odpowiedzi. Aby usunąć parametry adresu URL, użyj

$location.url($location.path());
alecswan
źródło
Myślę, że chciałeś umieścić ścieżkę w $ location.url () zamiast $ location.path. Próba połączenia ich obu jak powyżej nie działa dla mnie.
mbdev,
1
na mnie też nie działa. Obie funkcje pozostawiają tam parametr zapytania.
Pablo Ezequiel Leone
rzeczywiście pomocna odpowiedź. W moim scenariuszu za każdym razem, gdy po raz pierwszy wywołałem wywołanie $ location.path ('/ reportmaint'). Search ({<myparams>}), nigdy nie wyczyściło ono poprzednich parametrów zapytania.
bob.mazzo
powoduje to pętlę przycisku Wstecz w przeglądarce Chrome, ponieważ przycisk Wstecz wraca do //example.com?key=value, ale kątowo prowadzi do //example.com. Propozycje?
jaybro
+1 dlaThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Vlada
70

Aby usunąć WSZYSTKIE parametry zapytania, wykonaj:

$location.search({});

Aby usunąć JEDEN konkretny parametr zapytania, wykonaj:

$location.search('myQueryParam', null);
Rahul Desai
źródło
2
Działa również w Angular 1.5.
Manish M Demblani
1
działa również undefinedna wypadek, gdybyś unikał używania nulltakiego, jak ja.
HankScorpio
Nie podoba mi się to, że jeśli wrócisz za pomocą przycisku wstecz w przeglądarce, tracisz zapytanie wyszukiwania, które wykonałem tuż przed na mojej poprzedniej stronie wyszukiwania.
Gino
@Gino Aby obejść ten problem, możesz dodać wpis do historii przeglądarki przed resetowaniem. stackoverflow.com/q/10541388/586051
Rahul Desai
@RahulDesai Używam ng-route, trudno mi zrobić to automatycznie
Gino
29

Aby wyczyścić element, usuń go i zadzwoń do $$ redaguj

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

pochodzi ze źródła angularjs: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443

basarat
źródło
2
znakomity! Działał jak urok.
paulcpederson
To zadziałało dla mnie, ale zakładam, że rozwiązanie Juliusa jest bardziej poprawne, ponieważ wydaje się, że właśnie to mieli na myśli faceci z Angular, kiedy tworzyli searchmetodę. docs.angularjs.org/api/ng/service/$location#search
zmilojko
1
Dzięki, to działało całkiem nieźle ... Co ciekawe, IE8 lubi ustawiać / komponować ten adres URL, a następnie ładować go później. Jestem pewien, że właśnie dlatego preferowane jest właściwe trasowanie, a także dlaczego wszyscy jesteśmy złymi ludźmi. : P
Romanulus
27

Możesz usunąć określony parametr zapytania przy użyciu:

delete $location.$$search.nameOfParameter;

Lub możesz wyczyścić wszystkie parametry zapytania, ustawiając wyszukiwanie na pusty obiekt:

$location.$$search = {};
Quintin
źródło
2
Nie wiem dlaczego, ale to rozwiązanie nie działa dobrze podczas przełączania stron (parametry mogą pojawić się ponownie, nawet jeśli $location.$$search = {}zostanie wykonane). Rozwiązanie @basarat działa dobrze.
Mik378
1
U mnie zadziałało - może sprawdź kolejność w jakiej usuwasz parametr i zmieniasz ścieżkę?
demaniak
1
Chociaż może to zadziałać, uzyskuje dostęp do zmiennych prywatnych, których nie należy modyfikować, zobacz odpowiedź @Julius dla innego rozwiązania
Ben Taliadoros
26

W chwili pisania tego tekstu, jak wcześniej wspomniał @Bosh, html5modemusi truebyć możliwe ustawienie$location.search() i odzwierciedlić z powrotem w wizualnym adresie URL okna.

Zobacz https://github.com/angular/angular.js/issues/1521 uzyskać więcej informacji, .

Ale jeśli html5mode taktrue , możesz łatwo wyczyścić ciąg zapytania adresu URL za pomocą:

$location.search('');

lub

$location.search({});

Spowoduje to również zmianę wizualnego adresu URL okna.

(Testowane w wersji AngularJS 1.3.0-rc.1z html5Mode(true).)

Fredric
źródło
12

Musisz sprawić, by działało, gdy html5mode= false?

Wszystkie inne odpowiedzi działają tylko wtedy, gdy jest html5modeto Angular true. Jeśli pracujesz poza nim html5mode, $locationodnosi się tylko do „fałszywej” lokalizacji, która znajduje się w twoim hashu - i tak dalej$location.search nie możesz zobaczyć / edytować / naprawić parametrów wyszukiwania rzeczywistej strony.

Oto obejście, które należy wstawić do kodu HTML strony przed obciążeniami kątowymi:

<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>
Brednie
źródło
2
Innym sposobem, w jaki uniknąłem konfigurowania html5Mode na true, jest utworzenie ciągu zapytania w taki sposób, aby zawierał # tuż przed ? . więc myapp/#?client=clientName zamiast myapp/?client=clientName
Angel Gao
5

Po prostu użyj

$location.url();

Zamiast

$location.path();
kevinius
źródło
4

Jeśli chcesz przejść do innego adresu URL i wyczyścić parametry zapytania, użyj:

$location.path('/my/path').search({});
felippe
źródło
1

Jeśli używasz parametrów tras, po prostu wyczyść $ routeParams

$routeParams= null;
Oswaldo Alvarez
źródło
1
Spowoduje to po prostu ustawienie zmiennej lokalnej $routeParamsna null. W rzeczywistości w ogóle nie wpłynie na parametry adresu URL w pasku adresu.
Eric F.
1

Co powiesz na ustawienie skrótu lokalizacji na null

$location.hash(null);
Bwyss
źródło
0

jeśli natychmiast przetworzysz parametry, a następnie przejdziesz do następnej strony, możesz umieścić znak zapytania na końcu nowej lokalizacji.

na przykład, gdybyś zrobił $ location.path ('/ nextPage');

możesz to zrobić zamiast tego: $ location.path ('/ nextPage?');

user5487176
źródło
0

Wypróbowałem powyższe odpowiedzi, ale nie mogłem ich zmusić do działania. Jedyny kod, który działał dla mnie, to$window.location.search = ''

Gwen Au
źródło
0

Mogę zastąpić wszystkie parametry zapytania tym pojedynczym wierszem: $location.search({});
łatwy do zrozumienia i łatwy sposób na ich usunięcie.

Lucas Reppe Welander
źródło
0

Przyjęta odpowiedź zadziałała dla mnie, ale musiałem poszukać trochę głębiej, aby naprawić problemy z przyciskiem Wstecz.

Zauważyłem, że jeśli utworzę link do strony za pomocą <a ui-sref="page({x: 1})">, usuń ciąg zapytania za pomocą$location.search('x', null) , nie dostaję dodatkowego wpisu w historii przeglądarki, więc przycisk Wstecz przenosi mnie z powrotem do miejsca, w którym zacząłem. Chociaż wydaje mi się, że jest to złe, ponieważ nie sądzę, aby Angular automatycznie usuwał ten wpis historii za mnie, jest to w rzeczywistości pożądane zachowanie w moim konkretnym przypadku użycia.

Problem polega na tym, że jeśli link do tej strony używając <a href="https://stackoverflow.com/page/?x=1">zamiast, a następnie usunąć ciąg kwerendy w ten sam sposób, to zrobić uzyskać dodatkowy wpis w mojej historii przeglądarki, więc muszę kliknąć przycisk Wstecz dwukrotnie , aby wrócić do miejsca, gdzie zacząłem . Jest to niespójne zachowanie, ale w rzeczywistości wydaje się to bardziej poprawne.

Mogę łatwo rozwiązać problem z hreflinkami za pomocą $location.search('x', null).replace(), ale wtedy powoduje to uszkodzenie strony, gdy wylądujesz na niej za pośrednictwem ui-sreflinku, więc to nie jest dobre.

Po wielu zabawach, oto poprawka, którą wymyśliłem:

W funkcji mojej aplikacji rundodałem to:

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

Następnie używam tego kodu, aby usunąć parametr ciągu zapytania:

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

if ($location.path() === $rootScope.locationPath) {
    $location.replace();
}
Muczeć
źródło
0

Dla Angular> 2 możesz przekazać null do wszystkich parametrów, które chcesz wyczyścić

this.router.navigate(['/yourRoute'], {queryParams:{params1: null, param2: null}})
Fateh Mohamed
źródło