Búsqueda de sitios web

¿Cómo puedo eliminar un parámetro de cadena de consulta en JavaScript?


¿Hay una mejor manera de eliminar un parámetro de una cadena de consulta en una URL en JavaScript estándar que usando una expresión regular?

Aquí está lo que he ideado hasta ahora, lo cual parece funcionar en mis pruebas, ¡pero no me gusta reinventar el análisis de cadenas de consulta!

function RemoveParameterFromUrl( url, parameter ) {

    if( typeof parameter == "undefined" || parameter == null || parameter == "" ) throw new Error( "parameter is required" );

    url = url.replace( new RegExp( "\\b" + parameter + "=[^&;]+[&;]?", "gi" ), "" ); "$1" );

    // remove any leftover crud
    url = url.replace( /[&;]$/, "" );

    return url;
}

Respuesta #1

"[&;]?" + parameter + "=[^&;]+"

Parece peligroso porque el parámetro ‘bar’ coincidiría:

?a=b&foobar=c

Además, fallaría si parameter contiene algún carácter que sea especial en RegExp, como ‘.’. Y no es una expresión regular global, por lo que solo eliminaría una instancia del parámetro.

No usaría una expresión regular simple para esto, analizaría los parámetros y perdería los que no quieras.

function removeURLParameter(url, parameter) {
    //prefer to use l.search if you have a location/link object
    var urlparts = url.split('?');   
    if (urlparts.length >= 2) {

        var prefix = encodeURIComponent(parameter) + '=';
        var pars = urlparts[1].split(/[&;]/g);

        //reverse iteration as may be destructive
        for (var i = pars.length; i-- > 0;) {    
            //idiom for string.startsWith
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {  
                pars.splice(i, 1);
            }
        }

        return urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : '');
    }
    return url;
}

Respuesta #2

Los navegadores modernos proporcionan la interfaz URLSearchParams para trabajar con los parámetros de búsqueda. La cual tiene el método delete que elimina un parámetro por nombre.

if (typeof URLSearchParams !== 'undefined') {
  const params = new URLSearchParams('param1=1&param2=2&param3=3')
  
  console.log(params.toString())
  
  params.delete('param2')
  
  console.log(params.toString())

} else {
  console.log(`Your browser ${navigator.appVersion} does not support URLSearchParams`)
}

Respuesta #3

Puedes cambiar la URL con:

window.history.pushState({}, document.title, window.location.pathname);

De esta manera, puedes sobrescribir la URL sin el parámetro de búsqueda, la uso para limpiar la URL después de tomar los parámetros GET.

Respuesta #4

Si es una instancia de URL, utiliza la función delete de searchParams

let url = new URL(location.href);
url.searchParams.delete('page');

Respuesta #5

No veo problemas importantes con una solución de expresiones regulares. Pero, no olvides conservar el identificador de fragmento (texto después del #).

Aquí está mi solución:

function RemoveParameterFromUrl(url, parameter) {
  return url
    .replace(new RegExp('[?&]' + parameter + '=[^&#]*(#.*)?$'), '$1')
    .replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1');
}

Y al punto de bobince, sí: necesitarías escapar los caracteres . en los nombres de los parámetros.

Respuesta #6

Copiado de la respuesta de bobince, pero hecho para soportar signos de interrogación en la cadena de consulta, por ejemplo

http://www.google.com/search?q=test???+something&aq=f

¿Es válido tener más de un signo de interrogación en una URL?

function removeUrlParameter(url, parameter) {
  var urlParts = url.split('?');

  if (urlParts.length >= 2) {
    // Get first part, and remove from array
    var urlBase = urlParts.shift();

    // Join it back up
    var queryString = urlParts.join('?');

    var prefix = encodeURIComponent(parameter) + '=';
    var parts = queryString.split(/[&;]/g);

    // Reverse iteration as may be destructive
    for (var i = parts.length; i-- > 0; ) {
      // Idiom for string.startsWith
      if (parts[i].lastIndexOf(prefix, 0) !== -1) {
        parts.splice(i, 1);
      }
    }

    url = urlBase + '?' + parts.join('&');
  }

  return url;
}

Respuesta #7

Aquí una solución que:

  1. utiliza URLSearchParams (no expresiones regulares difíciles de entender)
  2. actualiza la URL en la barra de búsqueda sin recargar
  3. mantiene todas las demás partes de la URL (por ejemplo, el hash)
  4. elimina el ? superfluo en la cadena de consulta si se eliminó el último parámetro
function removeParam(paramName) {
    let searchParams = new URLSearchParams(window.location.search);
    searchParams.delete(paramName);
    if (history.replaceState) {
        let searchString = searchParams.toString().length > 0 ? '?' + searchParams.toString() : '';
        let newUrl = window.location.protocol + "//" + window.location.host + window.location.pathname +  searchString + window.location.hash;
        history.replaceState(null, '', newUrl);
    }
}

Nota: como se señaló en otras respuestas, URLSearchParams no es compatible con IE, así que utiliza un polyfill.

Respuesta #8

Aquí está lo que estoy usando:

if (location.href.includes('?')) { 
    history.pushState({}, null, location.href.split('?')[0]); 
}

URL original: http://www.example.com/test/hello?id=123&foo=bar
URL de destino: http://www.example.com/test/hello

¡Ahora esta respuesta parece aún mejor! (aunque no está completamente probada)

Respuesta #9

Esta es una versión limpia eliminar el parámetro de consulta con la clase URL para los navegadores de hoy:

function removeUrlParameter(url, paramKey)
{
  var r = new URL(url);
  r.searchParams.delete(paramKey);
  return r.href;
}

URLSearchParams no es compatible con navegadores antiguos

https://caniuse.com/#feat=urlsearchparams

IE, Edge (inferior a 17) y Safari (inferior a 10.3) no soportan URLSearchParams dentro de la clase URL.

Polyfills

Solo polyfill de URLSearchParams

https://github.com/WebReflection/url-search-params

Completar Polyfill URL y URLSearchParams para que coincidan con las últimas especificaciones de WHATWG

https://github.com/lifaon74/url-polyfill

Respuesta #10

Cualquiera interesado en una solución con expresiones regulares, he creado esta función para agregar/eliminar/actualizar un parámetro de la cadena de consulta. No proporcionar un valor eliminará el parámetro, proporcionar uno agregará/actualizará el parámetro. Si no se proporciona una URL, se obtendrá de window.location. Esta solución también tiene en cuenta el ancla de la URL.

function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null)
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) 
                url += '#' + hash[1];
            return url;
        }
    }
    else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) 
                url += '#' + hash[1];
            return url;
        }
        else
            return url;
    }
}

ACTUALIZACIÓN

Había un error al eliminar el primer parámetro en la cadena de consulta, he reorganizado la expresión regular y la prueba para incluir una corrección.

ACTUALIZACIÓN 2

@schellmax actualización para solucionar la situación donde se pierde el símbolo de hashtag al eliminar una variable de la cadena de consulta justo antes de un hashtag

Artículos relacionados