Come posso eliminare un parametro della stringa di query in JavaScript?


127

Esiste un modo migliore per eliminare un parametro da una stringa di query in una stringa URL in JavaScript standard se non usando un'espressione regolare?

Ecco cosa ho escogitato finora che sembra funzionare nei miei test, ma non mi piace reinventare l'analisi delle querystring!

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

Risposte:


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

Sembra pericoloso perché il parametro 'bar' corrisponderebbe:

?a=b&foobar=c

Inoltre, fallirebbe se parametercontenesse caratteri speciali in RegExp, come '.'. E non è una regex globale, quindi rimuoverà solo un'istanza del parametro.

Non userei un semplice RegExp per questo, analizzerei i parametri e perderei quelli che non vuoi.

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

Un buon punto sulla barra che corrisponde al foobar. Ho aggiornato il mio regex originale per richiedere un? o un [&;] all'inizio. Leggendo anche la tua soluzione per considerarla ...
Matthew Lock,

5
Se vuoi sbarazzarti del "?" quando non ci sono parametri dopo la rimozione, aggiungi una condizione if per verificare se pars.length == 0, e se è 0, fai "url = urlparts [0]" invece di aggiungere "?".
johnmcaliley,

2
È sicuro confrontare il frammento di URL con encodeURIComponent (parametro)? Cosa succede se l'URL codifica il nome del parametro in modo diverso? Ad esempio "due% 20 parole" contro "due + parole". Per far fronte a questo, potrebbe essere meglio decodificare il nome del parametro e confrontarlo come una normale stringa.
Adrian Pronk,

9
Leggero miglioramento, in modo che quando viene rimosso il parametro URL finale, il '?' viene rimosso anche: cambia la riga url= urlparts[0]+'?'+pars.join('&');inurl= urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S

2
I parametri della query URL @ ktutnik / @ JonasAxelsson non fanno distinzione tra maiuscole e minuscole.
Bobince,

30

I browser moderni forniscono l' URLSearchParamsinterfaccia per lavorare con i parametri di ricerca. Che ha un deletemetodo che rimuove param per nome.

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
Nota che URLSearchParamsnon è supportato da IE, Edge 16 e iOS 10.2 Safari. (ref: caniuse.com/#feat=urlsearchparams )
khiav reoy

3
@khiavreoy Yeah. Come le prime due parole nella risposta danno lo stesso link :)
Yury Tarabanko

23

Copiato dalla risposta bobince, ma ha reso supportato i punti interrogativi nella stringa di query, ad es

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

È valido avere più di un punto interrogativo in un 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
Credo che la ???sintassi non sia valida e non dovrebbe mai verificarsi in un URL`.

@torazaburo Dai un'occhiata alla domanda stackover che ho pubblicato: "È valido avere più di un punto interrogativo in un URL?", la risposta sembra essere sì. Anche questo è stato anni fa, quindi non riesco a ricordare i dettagli ma ho riscontrato problemi quando questo non è stato gestito correttamente.
LukePH,

Non sto dicendo che non esistono nel mondo reale e probabilmente si vorrebbe essere in grado di gestirli, ma in un URL correttamente formato, il punto interrogativo è un "carattere riservato" e qualsiasi punto interrogativo diverso da quello l'introduzione dei parametri della query deve essere codificata nell'URL.

1
Potresti voler sostituire l'ultima riga con return url.endsWith("?") ? url.slice(0,-1) : url;per coprire il caso in cui il parametro da rimuovere è l'unico nella stringa di query
Konamiman,

@Konamiman Questo cambierebbe i dati dei parametri, ad esempio rimuovendo "aq" da: google.com/search?q=test???&aq=f ma capisco cosa intendi, sarebbe bello ripulire l'URL anche se il ? non fa alcun male. La logica deve solo assicurarsi l'ultimo? è anche il primo?
Luca

21

Non vedo grossi problemi con una soluzione regex. Ma non dimenticare di conservare l'identificatore di frammento (testo dopo il #).

Ecco la mia soluzione:

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

E a proposito di Bobince, sì, dovresti scappare dai .caratteri nei nomi dei parametri.


1
Ecco una regex migliorata che funziona quando il parametro non ha alcun valore (es. "Ex.com?removeMe") e non sostituirà il parametro in frammenti (es. "Ex.com?#&dont=removeMe") o percorsi (es. " ex.com/&dont=removeMe '):url.replace(new RegExp('^([^#]*\?)(([^#]*)&)?' + parameter + '(\=[^&#]*)?(&|#|$)' ), '$1$3$5').replace(/^([^#]*)((\?)&|\?(#|$))/,'$1$3$4')
Stephen M. Harris,

Questo non funzionerà Stephen M. Harris. Prova a dare una stringa vuota al tuo codice come parametro e guarda cosa succede ...
David Fischer,

15

Puoi modificare l'URL con:

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

in questo modo, puoi sovrascrivere l'URL senza il parametro di ricerca, lo uso per pulire l'URL dopo aver preso i parametri GET.


13

Chiunque sia interessato a una soluzione regex ho messo insieme questa funzione per aggiungere / rimuovere / aggiornare un parametro querystring. Non fornire un valore rimuoverà il parametro, fornendo uno aggiungerà / aggiornerà il parametro. Se non viene fornito alcun URL, verrà catturato da window.location. Questa soluzione prende in considerazione anche l'ancora dell'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;
    }
}

AGGIORNARE

Si è verificato un errore durante la rimozione del primo parametro nella stringa di query, ho rielaborato regex e testato per includere una correzione.

AGGIORNAMENTO 2

Aggiornamento @schellmax per correggere la situazione in cui si perde il simbolo hashtag quando si rimuove una variabile querystring direttamente prima di un hashtag


1
Questo non funziona se hai due stringhe di query e rimuovi la prima. L'URL passato diventa non valido perché il? viene rimosso quando dovrebbe essere conservato.
Blake Niemyjski,

1
@BlakeNiemyjski grazie per aver trovato quel bug, ho aggiornato lo script per includere una soluzione alternativa per il primo parametro
ellemayo

1
rimuoverà accidentalmente l'hash qui:UpdateQueryString('a', null, 'http://www.test.com?a=b#c');
schellmax,

Bella funzione, grazie. Cordiali saluti: durante l'utilizzo di questo con un ignore array array in ogni loop () `, potrebbe essere necessario definire un restringimento continuo urlper ogni iterazione sostitutiva. Ciò significa che è necessario inserire a valuenegli argomenti, che rimuoverà la metà della stringa di query. Per contrastare ciò, usa undefinedo nullper valueargomentazioni come:url_from_last_iteration = UpdateQueryString(current_ignore_key, undefined/null, url_from_last_iteration);
dhaupin,

7

Supponendo di voler rimuovere il parametro key = val dall'URI:

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

Funziona bene ma sfuggire al primo punto interrogativo nella regex non è necessario e può causare errori di linter: /([&?]key=val*$|key=val&|[?&]key=val(?=#))/potrebbe essere preferibile quando si utilizza un linter come eslint
quetzaluz,


6

Ecco una funzione completa per l'aggiunta e la rimozione di parametri basati su questa domanda e questa sintesi github: 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);
};

È possibile aggiungere parametri come questo:

updateQueryStringParam( 'myparam', 'true' );

E rimuovilo in questo modo:

updateQueryStringParam( 'myparam', null );

In questo thread molti hanno detto che probabilmente il regex non è la soluzione migliore / stabile ... quindi non sono sicuro al 100% se questa cosa ha dei difetti ma per quanto ho provato funziona abbastanza bene.


5

Questa è una versione pulita rimuove il parametro di query con la classe URL per i browser di oggi:

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

URLSearchParams non supportato sui vecchi browser

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

IE, Edge (sotto 17) e Safari (sotto 10.3) non supportano URLSearchParams all'interno della classe URL.

polyfills

Solo polyfill URLSearchParams

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

Completa URL Polyfill e URLSearchParams per abbinare le ultime specifiche WHATWG

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


4

Utilizzando 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 versione precedente come funzione

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

Da quello che posso vedere, nessuna delle precedenti può gestire parametri normali e parametri di array. Eccone uno.

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

Come usarlo:

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

Naturalmente, per aggiornare un parametro, basta rimuovere quindi aggiungere. Sentiti libero di fare una funzione fittizia per questo.


path.replace(new RegExp("&?"+param+"=[\\w]+", "g"), "");Vorrei cambiare la regex in modo [\\w]*da includere parametri come "param =" senza valori.
Tomas Prado,

2

Tutte le risposte su questo thread hanno un difetto nel fatto che non mantengono parti di ancoraggio / frammento degli URL.

Quindi se il tuo URL è simile a:

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

e sostituisci "parametro"

perderai il testo del tuo frammento.

Quanto segue è l'adattamento delle risposte precedenti (bobince via LukePH) che risolve questo problema:

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
Leggero miglioramento, in modo che quando viene rimosso il parametro URL finale, il '?' viene rimosso anche: cambia la riga url = urlBase+'?'+pars.join('&');inurl = urlBase + (pars.length > 0 ? '?' + pars.join('&') : "");
Cody S


2

Ecco una soluzione che:

  1. usa URLSearchParams (non è difficile capire regex)
  2. aggiorna l'URL nella barra di ricerca senza ricaricare
  3. mantiene tutte le altre parti dell'URL (ad es. hash)
  4. rimuove superflous? nella stringa di query se l'ultimo parametro è stato rimosso
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: come indicato in altre risposte URLSearchParams non è supportato in IE , quindi utilizzare un polyfill .


2

Se si tratta di un'istanza di URL, utilizzare la deletefunzione disearchParams

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

1

un'altra risposta diretta e più semplice sarebbe

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

Una versione modificata della soluzione di ssh_imov

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

Chiama così

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

una cosa da tenere a mente quando si invia il valore di param convert spazio a% 20
xeon zolt

0

Questo restituisce l'URL senza QUALSIASI parametro 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

Ho praticamente scritto la seguente funzione per elaborare i parametri url e ottenere lo stato finale come stringa e reindirizzare la pagina. Speriamo che ne tragga beneficio.

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

Ad esempio, quando faccio clic su un pulsante, desidero eliminare il valore della pagina e aggiungere il valore della categoria.

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

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

});

Penso che sia stato molto utile!


0

Sono contento che tu abbia fatto scorrere qui.

Ti suggerirei di risolvere questo compito con le prossime possibili soluzioni:

  1. Devi supportare solo i browser moderni (Edge> = 17) - usa l' API URLSearchParams.delete () . È nativo e ovviamente è il modo più conveniente per risolvere questo compito.
  2. Se questa non è un'opzione, potresti voler scrivere una funzione per farlo. Tale funzione fa
    • non modificare l'URL se un parametro non è presente
    • rimuovere il parametro URL senza un valore, come http://google.com/?myparm
    • rimuovere il parametro URL con un valore, come http://google.com/?myparm=1
    • rimuovere il parametro URL se è nell'URL due volte, come http://google.com?qp=1&qpqp=2&qp=1
    • Non utilizza il forloop e non modifica l'array durante il looping su di esso
    • è più funzionale
    • è più leggibile rispetto alle soluzioni regexp
    • Prima di utilizzare assicurati che il tuo URL non sia codificato

Funziona in IE> 9 (versione 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); 
}

Versione fantasia 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}`}`;  
}

Guarda come funziona qui


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())

Questa è una risposta a una domanda molto antica e che ha già una risposta accettata. Spiega che cosa ha da offrire questa risposta, nuova / diversa dalle altre risposte. Inoltre, le risposte dovrebbero includere spiegazioni e non solo codice.
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, '');

    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.