Domanda

Esiste un modo migliore per eliminare un parametro da una stringa di query in una stringa URL in JavaScript standard oltre a utilizzare 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;
}
È stato utile?

Soluzione

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

Sembra pericoloso perché il parametro "bar" corrisponde:

?a=b&foobar=c

Inoltre, fallirebbe se parametro contenesse 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;
}

Altri suggerimenti

Copiato dalla risposta bobince, ma ha reso supportati i punti interrogativi nella stringa della query, ad es.

http://www.google.com/search?q = test ??? + qualcosa di & amp; 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;
}

Browser moderni forniscono URLSearchParams per lavorare con i parametri di ricerca. Che ha il metodo delete 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`)
}

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

Ecco la mia soluzione:

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

E, a proposito di Bobince, sì, dovresti sfuggire ai caratteri . nei nomi dei parametri.

), '$1') .replace(new RegExp('([?&])' + parameter + '=[^&]*&'), '$1'); }

E, a proposito di Bobince, sì, dovresti sfuggire ai caratteri . nei nomi dei parametri.

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

Aggiorna

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 di @schellmax per correggere la situazione in cui il simbolo hashtag viene perso quando si rimuove una variabile querystring direttamente prima di un hashtag

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.

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

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

Ecco cosa sto usando:

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

URL originale: http://www.example.com/test/hello ? id = 123 & amp; foo = bar
URL di destinazione: http://www.example.com/test/hello

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

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

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

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

Dovresti usare una libreria per manipolare l'URI in quanto è più complicato di quanto sembri in superficie farlo da solo. Dai uno sguardo a http://medialize.github.io/URI.js/

Da quello che posso vedere, nessuno dei precedenti può gestire parametri normali e parametri di array. Eccone uno che lo fa.

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 si usa:

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 farne una funzione fittizia.

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:

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

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 in questo modo

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

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

Questa è una versione pulita rimuovi 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

Se sei in jQuery, c'è un buon plugin di manipolazione della stringa di query:

function removeQueryStringParameter(uri, key, value) 
{

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

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

    if (uri.match(re)) {

        return uri.replace(re, '');

    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top