web-dev-qa-db-fra.com

Comment puis-je supprimer un paramètre de chaîne de requête en JavaScript?

Existe-t-il un meilleur moyen de supprimer un paramètre d'une chaîne de requête dans une chaîne d'URL en JavaScript standard autrement qu'en utilisant une expression régulière?

Voici ce que j'ai trouvé jusqu'ici qui semble fonctionner dans mes tests, mais je n'aime pas réinventer l'analyse de chaîne de requête!

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;
}
105
Matthew Lock
"[&;]?" + parameter + "=[^&;]+"

Semble dangereux car le paramètre «bar» correspond à:

?a=b&foobar=c

De plus, cela échouera si parameter contient des caractères spéciaux dans RegExp, tels que ‘.’. Et comme ce n'est pas une expression rationnelle globale, cela ne supprimerait qu'une instance du paramètre.

Je ne voudrais pas utiliser un simple RegExp pour cela, je voudrais analyser les paramètres et perdre ceux que vous ne voulez pas.

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;
}
150
bobince

Copié à partir de la réponse bobince, mais le faisant supporter les points d'interrogation dans la chaîne de requête, par exemple

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

Est-il valide d'avoir plus d'un point d'interrogation dans une 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;
}
22
LukePH

Je ne vois pas de problèmes majeurs avec une solution regex. Mais n'oubliez pas de conserver l'identifiant du fragment (texte après le #). 

Voici ma solution:

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

Et pour répondre à votre question, oui, il vous faudrait échapper des caractères . dans les noms de paramètres.

16
Jared

Toute personne intéressée par une solution regex, j'ai mis en place cette fonction pour ajouter/supprimer/mettre à jour un paramètre de chaîne de requête. Ne pas fournir de valeur va supprimer le paramètre, en fournir une ajoutera/mettra à jour le paramètre. Si aucune URL n'est fournie, elle sera extraite de window.location. Cette solution prend également en compte l'ancre de l'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;
    }
}

METTRE À JOUR

Il y avait un bogue lors de la suppression du premier paramètre de la chaîne de requête, j'ai retravaillé la regex et testé pour inclure un correctif.

MISE À JOUR 2

@schellmax met à jour pour corriger la situation où le symbole de hashtag est perdu lors de la suppression d'une variable de chaîne de requête directement avant un hashtag

12
ellemayo

Les navigateurs modernes fournissent URLSearchParams interface pour travailler avec les paramètres de recherche. Qui a delete méthode qui supprime param par son nom. 

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`)
}

12
Yury Tarabanko

En supposant que vous souhaitiez supprimer le paramètre key = val de l'URI: 

function removeParam(uri) {
   return uri.replace(/([&\?]key=val*$|key=val&|[?&]key=val(?=#))/, '');
}
5
ssh_imov

Voici une fonction complète pour l’ajout et la suppression de paramètres basés sur cette question et ce github Gist: https://Gist.github.com/excalq/2961415

var updateQueryStringParam = function (key, value) {

    var baseUrl = [location.protocol, '//', location.Host, location.pathname].join(''),
        urlQueryString = document.location.search,
        newParam = key + '=' + value,
        params = '?' + newParam;

    // If the "search" string exists, then build params from it
    if (urlQueryString) {

        updateRegex = new RegExp('([\?&])' + key + '[^&]*');
        removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?');

        if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty

            params = urlQueryString.replace(removeRegex, "$1");
            params = params.replace( /[&;]$/, "" );

        } else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it

            params = urlQueryString.replace(updateRegex, "$1" + newParam);

        } else { // Otherwise, add it to end of query string

            params = urlQueryString + '&' + newParam;

        }

    }
    window.history.replaceState({}, "", baseUrl + params);
};

Vous pouvez ajouter des paramètres comme ceci:

updateQueryStringParam( 'myparam', 'true' );

Et supprimez-le comme ceci:

updateQueryStringParam( 'myparam', null );

Dans ce fil, beaucoup ont dit que l'expression rationnelle n'était probablement pas la meilleure solution/stable ... donc je ne suis pas sûr à 100% si cette chose a des défauts, mais dans la mesure où je l'ai testée, cela fonctionne plutôt bien.

4
Johannes Grandy

Vous pouvez changer l'URL avec:

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

de cette façon, vous pouvez écraser l'URL sans le paramètre de recherche, je l'utilise pour nettoyer l'URL après avoir pris les paramètres GET.

4
Santi Nunez

La version ci-dessus en fonction

function removeURLParam(url, param)
{
 var urlparts= url.split('?');
 if (urlparts.length>=2)
 {
  var prefix= encodeURIComponent(param)+'=';
  var pars= urlparts[1].split(/[&;]/g);
  for (var i=pars.length; i-- > 0;)
   if (pars[i].indexOf(prefix, 0)==0)
    pars.splice(i, 1);
  if (pars.length > 0)
   return urlparts[0]+'?'+pars.join('&');
  else
   return urlparts[0];
 }
 else
  return url;
}
3
Graham

Utilisation de jQuery:

function removeParam(key) {
    var url = document.location.href;
    var params = url.split('?');
    if (params.length == 1) return;

    url = params[0] + '?';
    params = params[1];
    params = params.split('&');

    $.each(params, function (index, value) {
        var v = value.split('=');
        if (v[0] != key) url += value + '&';
    });

    url = url.replace(/&$/, '');
    url = url.replace(/\?$/, '');

    document.location.href = url;
}
3
Huy Phạm

Vous devriez utiliser une bibliothèque pour manipuler les adresses URI, car il est plus compliqué qu'il n'y paraît à la surface de le faire vous-même. Jetez un oeil à: http://medialize.github.io/URI.js/

2
Ryan

Toutes les réponses sur ce fil ont un défaut en ce qu'elles ne préservent pas les parties d'ancrage/fragment des URL.

Donc, si votre URL ressemble à:

http://dns-entry/path?parameter=value#fragment-text

et vous remplacez 'paramètre'

vous allez perdre votre fragment de texte.

Ce qui suit est une adaptation des réponses précédentes (bobince via LukePH) qui résout ce problème:

function removeParameter(url, parameter)
{
  var fragment = url.split('#');
  var urlparts= fragment[0].split('?');

  if (urlparts.length>=2)
  {
    var urlBase=urlparts.shift(); //get first part, and remove from array
    var queryString=urlparts.join("?"); //join it back up

    var prefix = encodeURIComponent(parameter)+'=';
    var pars = queryString.split(/[&;]/g);
    for (var i= pars.length; i-->0;) {               //reverse iteration as may be destructive
      if (pars[i].lastIndexOf(prefix, 0)!==-1) {   //idiom for string.startsWith
        pars.splice(i, 1);
      }
    }
    url = urlBase + (pars.length > 0 ? '?' + pars.join('&') : '');
    if (fragment[1]) {
      url += "#" + fragment[1];
    }
  }
  return url;
}
2
Bret Weinraub

Voici ce que j'utilise:

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

URL d'origine: http://www.example.com/test/hello?id=123&foo=bar
URL de destination: http://www.example.com/test/hello

1
Basj

D'après ce que je peux voir, rien de ce qui précède ne peut gérer les paramètres normaux et les paramètres de tableau. En voici un qui fait.

function removeURLParameter(param, url) {
    url = decodeURI(url).split("?");
    path = url.length == 1 ? "" : url[1];
    path = path.replace(new RegExp("&?"+param+"\\[\\d*\\]=[\\w]+", "g"), "");
    path = path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");
    path = path.replace(/^&/, "");
    return url[0] + (path.length
        ? "?" + path
        : "");
}

function addURLParameter(param, val, url) {
    if(typeof val === "object") {
        // recursively add in array structure
        if(val.length) {
            return addURLParameter(
                param + "[]",
                val.splice(-1, 1)[0],
                addURLParameter(param, val, url)
            )
        } else {
            return url;
        }
    } else {
        url = decodeURI(url).split("?");
        path = url.length == 1 ? "" : url[1];
        path += path.length
            ? "&"
            : "";
        path += decodeURI(param + "=" + val);
        return url[0] + "?" + path;
    }
}

Comment l'utiliser:

url = location.href;
    -> http://example.com/?tags[]=single&tags[]=promo&sold=1

url = removeURLParameter("sold", url)
    -> http://example.com/?tags[]=single&tags[]=promo

url = removeURLParameter("tags", url)
    -> http://example.com/

url = addURLParameter("tags", ["single", "promo"], url)
    -> http://example.com/?tags[]=single&tags[]=promo

url = addURLParameter("sold", 1, url)
    -> http://example.com/?tags[]=single&tags[]=promo&sold=1

Bien sûr, pour mettre à jour un paramètre, supprimez puis ajoutez. N'hésitez pas à créer une fonction fictive pour cela.

1
Keir Simmons

Une version modifiée de la solution par ssh_imov

function removeParam(uri, keyValue) {
      var re = new RegExp("([&\?]"+ keyValue + "*$|" + keyValue + "&|[?&]" + keyValue + "(?=#))", "i"); 
      return uri.replace(re, '');
    }

Appelle comme ça

removeParam("http://google.com?q=123&q1=234&q2=567", "q1=234");
// returns http://google.com?q=123&q2=567
0
kiranvj

Ceci retourne l'URL sans TOUS les paramètres GET:

var href = document.location.href;
var search = document.location.search;
var pos = href.indexOf( search );
if ( pos !== -1 ){
    href = href.slice( 0, pos );
    console.log( href );
}
0
David Freimaucher

Il s'agit d'un paramètre de requête propre version remove avec la classe URL pour les navigateurs actuels:

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

URLSearchParams non pris en charge sur les anciens navigateurs

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

IE, Edge (inférieur à 17) et Safari (inférieur à 10.3) ne prennent pas en charge URLSearchParams dans la classe d'URL.

Polyfills

URLSearchParams uniquement polyfill

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

Complétez les adresses URL et PolySearch de Polyfill pour correspondre aux dernières spécifications du WHATWG

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

0
Heroselohim