AngularJS: Comment effacer les paramètres de requête dans l'URL?

135

Mon application AngularJS doit avoir accès au profil LinkedIn de l'utilisateur. Pour ce faire, je dois rediriger l'utilisateur vers une URL LinkedIn qui contient un paramètre de rappel redirect_uri qui indiquera à LinkedIn de rediriger l'utilisateur vers mon application Web et d'inclure un paramètre de requête "code" dans l'URL. C'est un flux Oauth 2.0 traditionnel.

Tout fonctionne très bien sauf que LinkedIn redirige l'utilisateur vers l'URL suivante:

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

Je voudrais supprimer ?code=XXX&state=YYYde l'URL afin de la rendre propre. L'utilisateur n'a pas besoin de voir les paramètres de requête que j'ai reçus de la redirection LinkedIn.

J'ai essayé $location.absUrl($location.path() + $location.hash()).replace(), mais cela garde les paramètres de requête dans l'URL.

Je suis également incapable d'extraire les paramètres de requête, par exemple "code", en utilisant ($location.search()).code. Cela semble avoir? avant # dans l'URL ci-dessus trompe Angular.

alecswan
la source

Réponses:

151

j'utilise

$location.search('key', null)

Comme cela supprime non seulement ma clé, mais la supprime de la visibilité sur l'URL.

Julius
la source
2
cela provoque une boucle de bouton de retour dans le chrome comme dans le bouton de retour revient à //example.com?key=value, mais angulaire en avant vers //example.com. Suggestions?
jaybro
2
Cela me semble un peu comme un problème de code. Angular ne devrait rien transmettre, à moins que vous n'ayez ajouté un roi de méthode. De plus, l'ajout de .replace () remplace l'entrée actuelle de l'historique.
Julius
viewModelHelper.navigateTo ('toto /'); persistait la chaîne de requête dans l'url foo, donc je l'ai corrigée en utilisant window.location.href = 'foo /'; au lieu.
jaybro le
2
N'utilisez pas window, utilisez plutôt la fenêtre $ d'Angular. Le test unitaire sera plus simple. Plus: docs.angularjs.org/api/ng/service/$window
Julius
Cette réponse fonctionne parfaitement si vous souhaitez supprimer un paramètre spécifique, merci.
Dexxo
107

J'ai fini par obtenir la réponse du forum AngularJS. Voir ce fil pour plus de détails


Le lien est vers un fil de discussion Google Groupes, qui est difficile à lire et ne fournit pas de réponse claire. Pour supprimer les paramètres d'URL, utilisez

$location.url($location.path());
alecswan
la source
Je pense que vous vouliez mettre le chemin dans $ location.url () au lieu de $ location.path. Essayer de les fusionner comme ci-dessus ne fonctionne pas pour moi.
mbdev
1
ne fonctionne pas pour moi aussi. Les deux fonctions y laissent le paramètre de requête.
Pablo Ezequiel Leone
réponse utile en effet. Dans mon scénario, chaque fois après la première fois que j'ai déclenché $ location.path ('/ reportmaint'). Search ({<myparams>}), il n'a jamais nettoyé les paramètres de requête précédents.
bob.mazzo
cela provoque une boucle de bouton de retour dans le chrome comme dans le bouton de retour revient à //example.com?key=value, mais angulaire en avant vers //example.com. Suggestions?
jaybro
+1 pourThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Vlad
70

Pour supprimer TOUS les paramètres de requête, procédez comme suit:

$location.search({});

Pour supprimer UN paramètre de requête particulier, procédez comme suit:

$location.search('myQueryParam', null);
Rahul Desai
la source
2
Fonctionne également pour Angular 1.5.
Manish M Demblani
1
fonctionne également avec undefined, au cas où vous éviteriez d'utiliser nullcomme moi.
HankScorpio
Ce que je n'aime pas, c'est que si vous revenez avec le bouton de retour du navigateur, vous perdez la requête de recherche que j'ai faite juste avant dans ma page de recherche précédente.
Gino
@Gino Pour contourner le problème, vous pouvez ajouter un enregistrement à l'historique du navigateur avant cette réinitialisation. stackoverflow.com/q/10541388/586051
Rahul Desai
@RahulDesai J'utilise ng-route, j'ai du mal à le faire automatiquement
Gino
29

Pour effacer un élément, supprimez-le et appelez $$ compose

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

dérivé de la source angularjs: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443

basarat
la source
2
brillant! A travaillé comme un charme.
paulcpederson
Cela a fonctionné pour moi, mais je suppose que la solution de Julius est plus correcte, car cela semble être ce que les gars d'Angular avaient à l'esprit lorsqu'ils ont créé la searchméthode. docs.angularjs.org/api/ng/service/$location#search
zmilojko
1
Merci, cela a très bien fonctionné ... Fait intéressant, IE8 aime définir / composer cette URL et la charger ensuite. Je suis sûr que c'est la raison pour laquelle un routage approprié est préféré et aussi pourquoi nous sommes tous de mauvaises personnes. : P
Romanulus
27

Vous pouvez supprimer un paramètre de requête spécifique en utilisant:

delete $location.$$search.nameOfParameter;

Ou vous pouvez effacer tous les paramètres de requête en définissant la recherche sur un objet vide:

$location.$$search = {};
Quintin
la source
2
Je ne sais pas pourquoi, mais cette solution ne fonctionne pas bien lors du changement de page (les paramètres peuvent réapparaître, même s'ils $location.$$search = {}sont exécutés). La solution @basarat fonctionne bien.
Mik378
1
Cela a bien fonctionné pour moi - peut-être vérifier la séquence dans laquelle vous supprimez le paramètre et changez le chemin?
demaniak
1
Bien que cela puisse fonctionner, il accède à des variables privées qui ne devraient pas être modifiées, voir la réponse @Julius pour une autre solution
Ben Taliadoros
26

Au moment de la rédaction, et comme mentionné précédemment par @Bosh, html5modedoit être trueen mesure de le définir $location.search()et de le refléter dans l'URL visuelle de la fenêtre.

Voir https://github.com/angular/angular.js/issues/1521 pour plus d'informations.

Mais si html5mode c'est le truecas, vous pouvez facilement effacer la chaîne de requête de l'URL avec:

$location.search('');

ou

$location.search({});

Cela modifiera également l'URL visuelle de la fenêtre.

(Testé en version AngularJS 1.3.0-rc.1avec html5Mode(true).)

Fredric
la source
12

Besoin de le faire fonctionner quand html5mode= false?

Toutes les autres réponses ne fonctionnent que lorsque Angular html5modeest true. Si vous travaillez en dehors de html5mode, alors se $locationréfère uniquement au "faux" emplacement qui vit dans votre hachage - et $location.searchne peut donc pas voir / modifier / corriger les paramètres de recherche de la page réelle.

Voici une solution de contournement, à insérer dans le HTML de la page avant les chargements angulaires:

<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>
Étalages
la source
2
J'ai également évité de configurer html5Mode sur true en créant la chaîne de requête de telle sorte qu'elle contienne le # juste avant le ? . ainsi avoir myapp/#?client=clientName au lieu de myapp/?client=clientName
Angel Gao
5

Juste utiliser

$location.url();

Au lieu de

$location.path();
kevinius
la source
4

Si vous souhaitez passer à une autre URL et effacer les paramètres de requête, utilisez simplement:

$location.path('/my/path').search({});
Felippe
la source
1

Si vous utilisez des paramètres de routes, effacez simplement $ routeParams

$routeParams= null;
Oswaldo Alvarez
la source
1
Cela définira simplement la variable locale $routeParamssur null. N'affectera pas du tout les paramètres d'URL dans la barre d'adresse.
Eric F.
1

Que diriez-vous simplement de définir le hachage de l'emplacement sur null

$location.hash(null);
Bwyss
la source
0

si vous traitez les paramètres immédiatement puis passez à la page suivante, vous pouvez mettre un point d'interrogation à la fin du nouvel emplacement.

par exemple, si vous auriez fait $ location.path ('/ nextPage');

vous pouvez le faire à la place: $ location.path ('/ nextPage?');

user5487176
la source
0

J'ai essayé les réponses ci-dessus mais je n'ai pas pu les faire fonctionner. Le seul code qui a fonctionné pour moi était$window.location.search = ''

Gwen Au
la source
0

Je peux remplacer tous les paramètres de requête par cette seule ligne: moyen $location.search({});
facile à comprendre et simple de les effacer.

Lucas Reppe Welander
la source
0

La réponse acceptée a fonctionné pour moi, mais j'avais besoin de creuser un peu plus pour résoudre les problèmes avec le bouton de retour.

Ce que j'ai remarqué, c'est que si je crée un lien vers une page en utilisant <a ui-sref="page({x: 1})">, puis que je supprime la chaîne de requête en utilisant $location.search('x', null), je n'obtiens pas d'entrée supplémentaire dans l'historique de mon navigateur, donc le bouton Précédent me ramène à mon point de départ. Bien que je pense que c'est faux parce que je ne pense pas qu'Angular devrait automatiquement supprimer cette entrée d'historique pour moi, c'est en fait le comportement souhaité pour mon cas d'utilisation particulier.

Le problème est que si je lien vers la page en utilisant la <a href="https://stackoverflow.com/page/?x=1">place, puis retirez la chaîne de requête de la même manière, je fais obtenir une entrée supplémentaire dans mon historique du navigateur, donc je dois cliquer sur le bouton retour deux fois pour revenir à l' endroit où j'ai commencé . C'est un comportement incohérent, mais en fait cela semble plus correct.

Je peux facilement résoudre le problème des hrefliens en utilisant $location.search('x', null).replace(), mais cela casse la page lorsque vous y arrivez via un ui-sreflien, donc ce n'est pas bon.

Après beaucoup de bidouilles, voici le correctif que j'ai trouvé:

Dans la runfonction de mon application, j'ai ajouté ceci:

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

Ensuite, j'utilise ce code pour supprimer le paramètre de chaîne de requête:

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

if ($location.path() === $rootScope.locationPath) {
    $location.replace();
}
Meuglement
la source
0

Pour Angular> 2 , vous pouvez passer null à tous les paramètres que vous souhaitez effacer

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