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


128

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'à présent et qui semble fonctionner dans mes tests, mais je n'aime pas réinventer l'analyse des chaînes de requêtes!

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

Réponses:


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

Cela semble dangereux car le paramètre 'bar' correspondrait:

?a=b&foobar=c

De plus, cela échouerait si parameter contenait des caractères spéciaux dans RegExp, tels que «.». Et ce n'est pas une expression régulière globale, donc cela ne supprimerait qu'une seule instance du paramètre.

Je n'utiliserais pas un simple RegExp pour cela, j'analyserais les paramètres et je perdrais 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;
}

Bon point sur la barre correspondant au foobar. J'ai mis à jour mon regex d'origine pour exiger un? ou un [&;] au début. Lisez également votre solution pour l'examiner ...
Matthew Lock

5
Si vous voulez vous débarrasser du "?" lorsqu'il n'y a pas de paramètres après la suppression, ajoutez une condition if pour tester si pars.length == 0, et si c'est 0, alors créez "url = urlparts [0]" au lieu d'ajouter le "?".
johnmcaliley

2
Est-il sûr de comparer le fragment d'URL avec encodeURIComponent (paramètre)? Que faire si l'URL encode le nom du paramètre différemment? Par exemple «deux% 20 mots» contre «deux + mots». Pour résoudre ce problème, il peut être préférable de décoder le nom du paramètre et de le comparer comme une chaîne normale.
Adrian Pronk

9
Amélioration légère, de sorte que lorsque le paramètre d'URL final est supprimé, le "?" est également supprimé: Changez la ligne url= urlparts[0]+'?'+pars.join('&');enurl= urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S

2
@ ktutnik / @ JonasAxelsson Les paramètres de requête d'URL ne sont pas naturellement insensibles à la casse.
bobince

30

Les navigateurs modernes fournissent une URLSearchParamsinterface pour travailler avec les paramètres de recherche. Qui a une deleteméthode qui supprime le paramètre 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`)
}


2
Notez que ce URLSearchParamsn'est pas pris en charge par IE, Edge 16 et iOS 10.2 Safari. (ref: caniuse.com/#feat=urlsearchparams )
khiav reoy

3
@khiavreoy Ouais. Comme les deux premiers mots de la réponse, donnez le même lien :)
Yury Tarabanko

23

Copié à partir de la réponse bobince, mais l'a fait prendre en charge 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;
}

2
Je pense que la ???syntaxe est invalide et ne devrait jamais apparaître dans une URL.

@torazaburo Jetez un œil à la question stackoverflow que j'ai postée: "Est-il valide d'avoir plus d'un point d'interrogation dans une URL?", la réponse semble être oui. De plus, c'était il y a des années, donc je ne me souviens pas des détails, mais j'ai rencontré des problèmes lorsque cela n'a pas été correctement géré.
LukePH le

Je ne dis pas qu'ils n'existent pas dans le monde réel, et on voudrait probablement pouvoir les gérer, mais dans une URL correctement formée, le point d'interrogation est un "caractère réservé" et tout point d'interrogation autre que celui-ci l'introduction des paramètres de requête doit être encodée en URL.

1
Vous pouvez remplacer la dernière ligne par return url.endsWith("?") ? url.slice(0,-1) : url;pour couvrir le cas où le paramètre à supprimer est le seul dans la chaîne de requête
Konamiman

@Konamiman Cela changerait les données des paramètres lorsque, par exemple, supprimait 'aq' de: google.com/search?q=test???&aq=f mais je comprends ce que vous voulez dire, ce serait bien de nettoyer l'URL même si le ? ne fait aucun mal. La logique a juste besoin de s'assurer que le dernier? est aussi le premier?.
LukePH

22

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 revenir au sujet de Bobince, oui - vous auriez besoin d'échapper des .caractères dans les noms de paramètres.


1
Voici une regex améliorée qui fonctionne lorsque le paramètre n'a pas de valeur (c'est-à-dire 'ex.com?removeMe'), et ne remplacera pas le paramètre dans les fragments (c'est-à-dire 'ex.com?#&dont=removeMe') ou les chemins (c'est-à-dire ' ex.com/&dont=removeMe '):url.replace(new RegExp('^([^#]*\?)(([^#]*)&)?' + parameter + '(\=[^&#]*)?(&|#|$)' ), '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4')
Stephen M. Harris

Cela ne fonctionnera pas Stephen M. Harris. Essayez de donner à votre code une chaîne vide en tant que paramètre et voyez ce qui se passe ...
David Fischer

15

Vous pouvez modifier 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.


13

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 supprimera 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é l'expression régulière et testé pour inclure un correctif.

MISE À JOUR 2

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


1
Cela ne fonctionne pas si vous avez deux chaînes de requête et supprimez la première. L'URL transmise devient invalide car le? est supprimée quand elle doit être conservée.
Blake Niemyjski

1
@BlakeNiemyjski merci d'avoir trouvé ce bogue, j'ai mis à jour le script pour inclure une solution de contournement pour le premier paramètre
ellemayo

1
supprimera accidentellement le hachage ici:UpdateQueryString('a', null, 'http://www.test.com?a=b#c');
schellmax

Fonction cool, merci. FYI: en utilisant ceci avec des clés de tableau ignorées dans chaque boucle () `, vous devrez peut-être définir une réduction constante urlpour chaque itération de remplacement. Mais cela signifie que vous devez entrer a valuedans les arguments, ce qui laissera la chaîne de requête à moitié supprimée. Pour contrer cela, utilisez undefinedou nullpour un valueargument comme:url_from_last_iteration = UpdateQueryString(current_ignore_key, undefined/null, url_from_last_iteration);
dhaupin

7

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(?=#))/, '');
}

Fonctionne bien mais échapper au premier point d'interrogation dans l'expression régulière est inutile et peut provoquer une erreur de linter: /([&?]key=val*$|key=val&|[?&]key=val(?=#))/ peut être préférable lors de l'utilisation d'un linter comme eslint
quetzaluz


6

Voici une fonction complète pour ajouter et supprimer des paramètres en fonction de cette question et de 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 celui-ci:

updateQueryStringParam( 'myparam', 'true' );

Et supprimez-le comme ceci:

updateQueryStringParam( 'myparam', null );

Dans ce fil, beaucoup ont dit que le regex n'est probablement pas la meilleure solution / stable ... donc je ne suis pas sûr à 100% si cette chose a des défauts, mais pour autant que je l'ai testé, cela fonctionne assez bien.


5

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

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 URL.

Polyfills

URLSearchParams uniquement polyfill

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

Complétez les URL Polyfill et URLSearchParams pour correspondre aux dernières spécifications WHATWG

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


4

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

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


2

D'après ce que je peux voir, aucun des éléments ci-dessus ne peut gérer les paramètres normaux et les paramètres de tableau. En voici un qui le 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, il suffit de supprimer puis d'ajouter. N'hésitez pas à en faire une fonction factice.


path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");Je changerais l'expression régulière pour [\\w]*inclure des paramètres comme "param =" sans valeurs.
Tomas Prado

2

Toutes les réponses de 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 perdrez votre texte fragmenté.

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

1
Amélioration légère, de sorte que lorsque le paramètre d'URL final est supprimé, le "?" est également supprimé: Changez la ligne url = urlBase+'?'+pars.join('&');enurl = urlBase + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S


2

Voici une solution qui:

  1. utilise URLSearchParams (pas de regex difficile à comprendre)
  2. met à jour l'URL dans la barre de recherche sans recharger
  3. conserve toutes les autres parties de l'URL (par exemple, le hachage)
  4. supprime superflous? dans la chaîne de requête si le dernier paramètre a été supprimé
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);
    }
}

Remarque: comme indiqué dans d'autres réponses, URLSearchParams n'est pas pris en charge dans IE , utilisez donc un polyfill .


2

S'il s'agit d'une instance de URL, utilisez la deletefonction desearchParams

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

1

une autre réponse directe et plus simple serait

let url = new URLSearchParams(location.search)
let key = 'some_key'

return url.has(key)
    ? location.href.replace(new RegExp(`[?&]${key}=${url.get(key)}`), '')
    : location.href

0

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, '');
    }

Appelez comme ça

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

une chose à garder à l'esprit lors de l'envoi de la valeur de l'espace de conversion des
paramètres

0

Cela renvoie l'URL sans aucun paramètre 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

J'ai pratiquement écrit la fonction suivante pour traiter les paramètres d'url et obtenir le statut final sous forme de chaîne et rediriger la page. Espérons que cela en profite.

function addRemoveUrlQuery(addParam = {}, removeParam = [], startQueryChar = '?'){

    let urlParams = new URLSearchParams(window.location.search);

    //Add param
    for(let i in addParam){
        if(urlParams.has(i)){ urlParams.set(i, addParam[i]); }
        else                { urlParams.append(i, addParam[i]); }
    }

    //Remove param
    for(let i of removeParam){
        if(urlParams.has(i)){
            urlParams.delete(i);
        }
    }

    if(urlParams.toString()){
        return startQueryChar + urlParams.toString();
    }

    return '';
}

Par exemple, lorsque je clique sur un bouton, je veux que la valeur de la page soit supprimée et que la valeur de la catégorie soit ajoutée.

let button = document.getElementById('changeCategory');
button.addEventListener('click', function (e) {

    window.location = addRemoveUrlQuery({'category':'cars'}, ['page']);

});

Je pense que c'était très utile!


0

Heureux que vous ayez fait défiler ici.

Je vous suggère de résoudre cette tâche par les prochaines solutions possibles:

  1. Vous devez prendre en charge uniquement les navigateurs modernes (Edge> = 17) - utilisez l' API URLSearchParams.delete () . Il est natif et constitue évidemment le moyen le plus pratique de résoudre cette tâche.
  2. Si ce n'est pas une option, vous souhaiterez peut-être écrire une fonction pour ce faire. Une telle fonction fait
    • ne changez pas l'URL si un paramètre n'est pas présent
    • supprimer le paramètre d'URL sans valeur, comme http://google.com/?myparm
    • supprimer le paramètre d'URL avec une valeur, comme http://google.com/?myparm=1
    • supprimer le paramètre d'URL s'il est dans l'URL deux fois, comme http://google.com?qp=1&qpqp=2&qp=1
    • N'utilise pas de forboucle et ne modifie pas le tableau pendant le bouclage dessus
    • est plus fonctionnel
    • est plus lisible que les solutions d'expression régulière
    • Avant d'utiliser, assurez-vous que votre URL n'est pas encodée

Fonctionne dans IE> 9 (version ES5)

function removeParamFromUrl(url, param) {  // url: string, param: string
  var urlParts = url.split('?'),
      preservedQueryParams = '';

  if (urlParts.length === 2) {
    preservedQueryParams = urlParts[1]
      .split('&')
      .filter(function(queryParam) {
        return !(queryParam === param || queryParam.indexOf(param + '=') === 0)
      })
      .join('&');
  }

  return urlParts[0] +  (preservedQueryParams && '?' + preservedQueryParams); 
}

Version fantaisie ES6

function removeParamFromUrlEs6(url, param) {
  const [path, queryParams] = url.split('?');
	let preservedQueryParams = '';

  if (queryParams) {
    preservedQueryParams = queryParams
      .split('&')
      .filter(queryParam => !(queryParam === param || queryParam.startsWith(`${param}=`)))
      .join('&');
  }

  return `${path}${preservedQueryParams && `?${preservedQueryParams}`}`;  
}

Découvrez comment cela fonctionne ici


0
function removeParamInAddressBar(parameter) {
    var url = document.location.href;
    var urlparts = url.split('?');

    if (urlparts.length >= 2) {
        var urlBase = urlparts.shift();
        var queryString = urlparts.join("?");

        var prefix = encodeURIComponent(parameter) + '=';
        var pars = queryString.split(/[&;]/g);
        for (var i = pars.length; i-- > 0;) {
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {
                pars.splice(i, 1);
            }
        }

        if (pars.length == 0) {
            url = urlBase;
        } else {
            url = urlBase + '?' + pars.join('&');
        }

        window.history.pushState('', document.title, url); // push the new url in address bar
    }
    return url;
}

-1
const params = new URLSearchParams(location.search)
params.delete('key_to_delete')
console.log(params.toString())

C'est une réponse à une question très ancienne et qui a déjà une réponse acceptée. Veuillez expliquer ce que cette réponse a à offrir, qui est nouvelle / différente des autres réponses. En outre, les réponses doivent inclure des explications et pas seulement du code.
nurdyguy


-2
function removeQueryStringParameter(uri, key, value) 
{

var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");

    var separator = uri.indexOf('?') !== -1 ? "&" : "?";

    if (uri.match(re)) {

        return uri.replace(re, '');

    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.