AngularJS: Como limpar os parâmetros de consulta na URL?

135

Meu aplicativo AngularJS precisa ter acesso ao perfil do usuário no LinkedIn. Para fazer isso, preciso redirecionar o usuário para uma URL do LinkedIn que contenha um parâmetro de retorno de chamada redirect_uri que instruirá o LinkedIn a redirecionar o usuário de volta ao meu aplicativo da web e incluir um parâmetro de consulta "código" no URL. É um fluxo tradicional do Oauth 2.0.

Tudo funciona muito bem, exceto que o LinkedIn redireciona o usuário de volta para o seguinte URL:

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

Gostaria de remover ?code=XXX&state=YYYdo URL para torná-lo limpo. O usuário não precisa ver os parâmetros de consulta que recebi do redirecionamento do LinkedIn.

Eu tentei $location.absUrl($location.path() + $location.hash()).replace(), mas ele mantém os parâmetros de consulta na URL.

Também não consigo extrair os parâmetros de consulta, por exemplo, "código", usando ($location.search()).code. Parece ter? antes de # no URL acima estar enganando Angular.

alecswan
fonte

Respostas:

151

eu uso

$location.search('key', null)

Como isso não apenas exclui minha chave, mas a remove da visibilidade na URL.

Julius
fonte
2
isso causa um loop do botão voltar no chrome, pois o botão voltar volta para //example.com?key=value, mas é encaminhado angularmente para //example.com. Sugestões?
Jaybro 31/08/2015
2
Isso me parece um problema de código. Angular não deve encaminhar nada, a menos que haja algum rei de método adicionado por você. Além disso, adicionar .replace () substitui a entrada do histórico atual.
Julio
viewModelHelper.navigateTo ('foo /'); estava persistindo a string de consulta no foo url, então eu o corrigi usando window.location.href = 'foo /'; em vez de.
jaybro
2
Não use window, use a janela $ do Angular. Será mais fácil fazer o teste de unidade. Mais: docs.angularjs.org/api/ng/service/$window
Julius
Esta resposta funciona perfeitamente se você deseja excluir um parâmetro específico, obrigado.
Dexxo
107

Acabei recebendo a resposta do fórum AngularJS. Veja este tópico para detalhes


O link é para um segmento dos Grupos do Google, que é difícil de ler e não fornece uma resposta clara. Para remover os parâmetros de URL, use

$location.url($location.path());
alecswan
fonte
Eu acho que você quis colocar o caminho em $ location.url () em vez de $ location.path. Tentar mesclar os dois como acima não funciona para mim.
mbdev
1
não funciona para mim também. Ambas as funções deixam o parâmetro de consulta lá.
Pablo Ezequiel Leone
resposta útil de fato. No meu cenário, sempre que após a primeira vez que acionei $ location.path ('/ reportmaint'). Search ({<myparams>}), ele nunca limpou os parâmetros de consulta anteriores.
bob.mazzo
isso causa um loop do botão voltar no chrome, pois o botão voltar volta para //example.com?key=value, mas é encaminhado angularmente para //example.com. Sugestões?
jaybro
+1 paraThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Vlad
70

Para remover TODOS os parâmetros de consulta, faça:

$location.search({});

Para remover UM parâmetro de consulta específico, faça:

$location.search('myQueryParam', null);
Rahul Desai
fonte
2
Funciona para Angular 1.5 também.
Manish M Demblani 30/03
1
também funciona undefined, caso você esteja evitando usar nullcomo eu.
HankScorpio
O que eu não gosto é que, se você voltar com o botão Voltar do navegador, perderá a consulta de pesquisa que fiz anteriormente na minha página de pesquisa anterior.
Gino
@Gino Como solução alternativa, você pode adicionar um registro ao histórico do navegador antes dessa redefinição. stackoverflow.com/q/10541388/586051
Rahul Desai
@RahulDesai Estou usando ng-rota, i resistente ele irá fazê-lo automaticamente
Gino
29

Para limpar um item, exclua-o e chame $$ componete

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

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

basarat
fonte
2
brilhante! Funcionou como um encanto.
Paulcpederson # 23/14
Isso funcionou para mim, mas eu diria que a solução de Julius é mais correta, pois parece ser o que os caras do Angular tinham em mente quando criaram o searchmétodo. docs.angularjs.org/api/ng/service/$location#search
zmilojko
1
Obrigado, isso funcionou muito bem ... Curiosamente, o IE8 gosta de definir / compor esse URL e carregá-lo posteriormente. Tenho certeza de que é por isso que o roteamento adequado é preferido e também porque somos todos pessoas más. : P
Romanulus 16/02
27

Você pode excluir um parâmetro de consulta específico usando:

delete $location.$$search.nameOfParameter;

Ou você pode limpar todos os parâmetros de consulta configurando a pesquisa para um objeto vazio:

$location.$$search = {};
Quintin
fonte
2
Não sei por que, mas essa solução não funciona bem ao alternar entre páginas (os parâmetros podem reaparecer, mesmo que $location.$$search = {}sejam executados). A solução @basarat está funcionando bem.
precisa saber é o seguinte
1
Funcionou bem para mim - talvez verifique a sequência em que você está removendo o parâmetro e alterando o caminho?
demaniak
1
Embora isso possa trabalhar ele acessa variáveis privadas que não devem ser modificados, ver a resposta @Julius outra solução
Ben Taliadoros
26

No momento da redação deste artigo, e como mencionado anteriormente pelo @Bosh, html5modeé truenecessário poder definir $location.search()e refletir a URL visual da janela.

Consulte https://github.com/angular/angular.js/issues/1521 para obter mais informações.

Mas se html5mode for,true você pode facilmente limpar a string de consulta da URL com:

$location.search('');

ou

$location.search({});

Isso também altera o URL visual da janela.

(Testado na versão AngularJS 1.3.0-rc.1com html5Mode(true).)

Fredric
fonte
12

Precisa fazê-lo funcionar quando html5mode= false?

Todas as outras respostas funcionam apenas quando Angular html5modeé true. Se você trabalha fora html5mode, $locationrefere - se apenas ao local "falso" que reside no seu hash - e, portanto, $location.searchnão pode ver / editar / corrigir os parâmetros de pesquisa da página real.

Aqui está uma solução alternativa, a ser inserida no HTML da página antes do carregamento angular:

<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
fonte
2
Outra maneira de evitar a configuração do html5Mode como true é criando a string de consulta, de forma que ela contenha o # logo antes do ? . então tem em myapp/#?client=clientName vez de myapp/?client=clientName
Angel Gao
5

Apenas use

$location.url();

Ao invés de

$location.path();
kevinius
fonte
4

Se você deseja mover para outro URL e limpar os parâmetros de consulta, basta usar:

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

Se você estiver usando parâmetros de rotas, limpe $ routeParams

$routeParams= null;
Oswaldo Alvarez
fonte
1
Isso apenas definirá a variável local $routeParamscomo null. Na verdade, não afetará os parâmetros de URL na barra de endereço.
Eric F.
1

Que tal apenas definir o hash do local como nulo

$location.hash(null);
Bwyss
fonte
0

se você processar os parâmetros imediatamente e passar para a próxima página, poderá colocar um ponto de interrogação no final do novo local.

por exemplo, se você tivesse feito $ location.path ('/ nextPage');

você pode fazer isso: $ location.path ('/ nextPage?');

user5487176
fonte
0

Eu tentei as respostas acima, mas não consegui fazê-las funcionar. O único código que funcionou para mim foi$window.location.search = ''

Gwen Au
fonte
0

Posso substituir todos os parâmetros de consulta por esta única linha: $location.search({});
Fácil de entender e fácil de limpá-los.

Lucas Reppe Welander
fonte
0

A resposta aceita funcionou para mim, mas eu precisava me aprofundar um pouco mais para corrigir os problemas com o botão Voltar.

O que eu notei é que, se eu vincular uma página usando <a ui-sref="page({x: 1})">e remover a string de consulta usando $location.search('x', null), não recebo uma entrada extra no histórico do navegador; portanto, o botão Voltar me leva de volta para onde comecei. Embora eu ache que isso esteja errado, porque não acho que o Angular remova automaticamente essa entrada do histórico para mim, esse é realmente o comportamento desejado para o meu caso de uso específico.

O problema é que se eu ligar para a página usando <a href="https://stackoverflow.com/page/?x=1">em vez disso, em seguida, remover a string de consulta da mesma forma, eu faço obter uma entrada extra no meu histórico do navegador, então eu tenho que clicar no botão Voltar duas vezes para voltar para onde eu comecei . Esse é um comportamento inconsistente, mas na verdade isso parece mais correto.

Posso corrigir facilmente o problema com os hreflinks usando $location.search('x', null).replace(), mas isso interrompe a página quando você acessa a página por meio de um ui-sreflink, então isso não é bom.

Depois de muitas brincadeiras, essa é a solução que eu criei:

Na runfunção do meu aplicativo, adicionei isso:

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

Então eu uso esse código para remover o parâmetro da string de consulta:

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

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

Para Angular> 2 , você pode passar nulo a todos os parâmetros que deseja limpar

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