AngularJS: ¿Cómo borrar los parámetros de consulta en la URL?

135

Mi aplicación AngularJS necesita tener acceso al perfil de usuario de LinkedIn. Para hacer eso, necesito redirigir al usuario a una URL de LinkedIn que contiene un parámetro de devolución de llamada redirect_uri que le indicará a LinkedIn que redirija al usuario de nuevo a mi aplicación web e incluya un parámetro de consulta de "código" en la URL. Es un flujo tradicional de Oauth 2.0.

Todo funciona muy bien, excepto que LinkedIn redirige al usuario a la siguiente URL:

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

Me gustaría eliminar ?code=XXX&state=YYYde la URL para que quede limpia. El usuario no necesita ver los parámetros de consulta que recibí de la redirección de LinkedIn.

Lo intenté $location.absUrl($location.path() + $location.hash()).replace(), pero mantiene los parámetros de consulta en la URL.

Tampoco puedo extraer los parámetros de consulta, por ejemplo, "código", usando ($location.search()).code. Parece que tiene? antes de # en la URL anterior está engañando a Angular.

alecswan
fuente

Respuestas:

151

yo suelo

$location.search('key', null)

Como esto no solo elimina mi clave, sino que la elimina de la visibilidad en la URL.

Julius
fuente
2
esto provoca un bucle de botón de retroceso en cromo ya que en el botón de retroceso vuelve a //example.com?key=value, pero angular hacia adelante a //example.com. Sugerencias?
jaybro
2
Esto me parece un problema de código. Angular no debe reenviar nada, a menos que haya agregado un rey de método. Además, agregar .replace () reemplaza la entrada actual del historial.
Julio
viewModelHelper.navigateTo ('foo /'); persistía la cadena de consulta en la url foo, por lo que lo arreglé usando window.location.href = 'foo /'; en lugar.
jaybro
2
No use window, use $ window de Angular en su lugar. Será más fácil realizar pruebas unitarias. Más: docs.angularjs.org/api/ng/service/$window
Julio
Esta respuesta funciona perfecto si desea eliminar un parámetro específico, gracias.
Dexxo el
107

Terminé recibiendo la respuesta del foro AngularJS. Ver este hilo para más detalles


El enlace es a un hilo de Grupos de Google, que es difícil de leer y no proporciona una respuesta clara. Para eliminar los parámetros de URL use

$location.url($location.path());
alecswan
fuente
Creo que querías poner la ruta en $ location.url () en lugar de $ location.path. Intentar fusionarlos a los dos como arriba no funciona para mí.
mbdev
1
A mí tampoco me funciona. Ambas funciones dejan el parámetro de consulta allí.
Pablo Ezequiel Leone
respuesta útil de hecho. En mi escenario, cada vez después de la primera vez que activé $ location.path ('/ reportmaint'). Search ({<myparams>}), nunca borró los parámetros de consulta anteriores.
bob.mazzo
esto provoca un bucle de botón de retroceso en cromo ya que en el botón de retroceso vuelve a //example.com?key=value, pero angular hacia adelante a //example.com. Sugerencias?
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 eliminar TODOS los parámetros de consulta, haga:

$location.search({});

Para eliminar UN parámetro de consulta particular, haga:

$location.search('myQueryParam', null);
Rahul Desai
fuente
2
Funciona para Angular 1.5 también.
Manish M Demblani
1
también funciona con undefined, en caso de que estés evitando usar nullcomo soy.
HankScorpio
Lo que no me gusta es que si vuelves con el botón de retroceso del navegador, pierdes la consulta de búsqueda que hice justo antes en mi página de búsqueda anterior.
Gino
@Gino Como solución alternativa, puede agregar un registro al historial del navegador antes de este restablecimiento. stackoverflow.com/q/10541388/586051
Rahul Desai
@RahulDesai Estoy usando ng-route, creo que lo hará automáticamente
Gino
29

Para borrar un elemento, bórrelo y llame a $$ compose

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

derivado de la fuente angularjs: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443

basarat
fuente
2
¡brillante! Trabajado como un encanto.
Paulcpederson
Esto funcionó para mí, pero supongo que la solución de Julius es más correcta, ya que parece ser lo que los chicos angulares tenían en mente cuando crearon el searchmétodo. docs.angularjs.org/api/ng/service/$location#search
zmilojko
1
Gracias, esto funcionó bastante bien ... Curiosamente, a IE8 le gusta configurar / componer esa URL y luego cargarla posteriormente. Estoy seguro de que es por eso que se prefiere el enrutamiento adecuado y también por qué todos somos malas personas. : P
Romanulus
27

Puede eliminar un parámetro de consulta específico utilizando:

delete $location.$$search.nameOfParameter;

O puede borrar todos los parámetros de consulta configurando la búsqueda en un objeto vacío:

$location.$$search = {};
Quintin
fuente
2
No sé por qué, pero esta solución no funciona bien al cambiar de página (los parámetros pueden reaparecer, incluso si $location.$$search = {}se ejecuta). La solución @basarat funciona bien.
Mik378
1
Funcionó bien para mí, ¿tal vez verifique la secuencia en la que está eliminando el parámetro y cambiando la ruta?
demaniak
1
Aunque esto puede funcionar, accede a variables privadas que no deberían modificarse, consulte la respuesta de @Julius para otra solución
Ben Taliadoros,
26

En el momento de la escritura, y como se mencionó anteriormente por @Bosh, html5modedebe estar trueen orden para poder configurarlo $location.search()y que se refleje de nuevo en la URL visual de la ventana.

Consulte https://github.com/angular/angular.js/issues/1521 para obtener más información.

Pero si html5mode estrue así, puede borrar fácilmente la cadena de consulta de la URL con:

$location.search('');

o

$location.search({});

Esto también alterará la URL visual de la ventana.

(Probado en la versión AngularJS 1.3.0-rc.1con html5Mode(true).)

Fredric
fuente
12

¿Necesita hacer que funcione cuando html5mode= false?

Todas las otras respuestas funcionan solo cuando Angular html5modees true. Si está trabajando fuera de html5mode, entonces se $locationrefiere solo a la ubicación "falsa" que vive en su hash, por $location.searchlo que no puede ver / editar / corregir los parámetros de búsqueda de la página real.

Aquí hay una solución alternativa, que se insertará en el HTML de la página antes de las cargas angulares:

<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>
Tonterías
fuente
2
Otra forma en que evité configurar html5Mode en true es creando la cadena de consulta de modo que contenga el # justo antes de ? . así que en myapp/#?client=clientName lugar de myapp/?client=clientName
Angel Gao
5

Solo usa

$location.url();

En vez de

$location.path();
kevinius
fuente
4

Si desea pasar a otra URL y borrar los parámetros de consulta, simplemente use:

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

Si está utilizando parámetros de rutas, simplemente borre $ routeParams

$routeParams= null;
Oswaldo Alvarez
fuente
1
Esto solo establecerá la variable local $routeParamsen null. En realidad, no afectará a los parámetros de URL en la barra de direcciones.
Eric F.
1

¿Qué tal simplemente establecer el hash de ubicación en nulo?

$location.hash(null);
Bwyss
fuente
0

Si procesa los parámetros inmediatamente y luego pasa a la página siguiente, puede colocar un signo de interrogación al final de la nueva ubicación.

por ejemplo, si hubiera hecho $ location.path ('/ nextPage');

puede hacer esto en su lugar: $ location.path ('/ nextPage?');

usuario5487176
fuente
0

He intentado las respuestas anteriores pero no pude hacer que funcionen. El único código que funcionó para mí fue$window.location.search = ''

Gwen Au
fuente
0

Puedo reemplazar todos los parámetros de consulta con esta única línea: $location.search({});
fácil de entender y una forma fácil de borrarlos.

Lucas Reppe Welander
fuente
0

La respuesta aceptada funcionó para mí, pero necesitaba profundizar un poco más para solucionar los problemas con el botón Atrás.

Lo que noté es que si enlazo a una página usando <a ui-sref="page({x: 1})">, luego elimino la cadena de consulta usando $location.search('x', null), no obtengo una entrada adicional en el historial de mi navegador, por lo que el botón Atrás me lleva de regreso a donde comencé. Aunque siento que esto está mal porque no creo que Angular deba eliminar automáticamente esta entrada del historial, este es realmente el comportamiento deseado para mi caso de uso particular.

El problema es que si me enlace a la página utilizando <a href="https://stackoverflow.com/page/?x=1">en su lugar, a continuación, quitar la cadena de consulta de la misma manera, yo hago conseguir una entrada extra en mi historial del navegador, por lo que tengo que hacer clic en el botón Atrás dos veces para volver al punto de partida . Este es un comportamiento inconsistente, pero en realidad esto parece más correcto.

Puedo solucionar fácilmente el problema con los hrefenlaces mediante el uso $location.search('x', null).replace(), pero esto rompe la página cuando aterrizas a través de un ui-srefenlace, por lo que esto no es bueno.

Después de mucho juguetear, esta es la solución que se me ocurrió:

En la runfunción de mi aplicación, agregué esto:

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

Luego uso este código para eliminar el parámetro de cadena de consulta:

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

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

Para Angular> 2 , puede pasar nulo a todos los parámetros que desea borrar

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