Come posso aggiungere o aggiornare un parametro della stringa di query?


364

Con javascript come posso aggiungere un parametro stringa di query all'URL se non presente o, se presente, aggiornare il valore corrente? Sto usando jquery per lo sviluppo del mio lato client.


1
Sembra che abbia scritto la funzione "parseQueryString" in JavaScript circa 100 volte durante la mia carriera. Non è difficile. Punti chiave, String#splitaccetta un secondo parametro per divisioni massime. Anche jQuery mapsarà utile.
jpsimons,

Questo post SO ha anche molte soluzioni stackoverflow.com/questions/1090948/…
Dilip Rajkumar

1
Alcune persone stanno rispondendo a questa domanda per indicare "come modificare l'URL nella barra degli indirizzi" e altri "come modificare qualsiasi variabile URL"
PandaWood,

Risposte:


468

Ho scritto la seguente funzione che realizza ciò che voglio ottenere:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
  var separator = uri.indexOf('?') !== -1 ? "&" : "?";
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  }
  else {
    return uri + separator + key + "=" + value;
  }
}

36
Questa risposta non funziona quando è presente un hash nell'URI: le stringhe di query devono essere posizionate prima dell'hash, altrimenti non vengono inviate al server. jsfiddle.net/4yXzR
Greg

20
[?|&]dovrebbe essere[?&]
soju,

8
Limitare l'ambito della variabile separatore alla funzione locale aggiungendo varsubito prima della dichiarazione del separatore.
Andrea Salicetti,

3
Penso che dovresti aggiungere value = encodeURIComponent(value);la prima riga, altrimenti le interruzioni di riga non vengono salvate correttamente.
Felix,

18
Questo si occuperà anche dell'hash: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz

189

Ho ampliato la soluzione e l'ho combinata con un'altra che ho trovato per sostituire / aggiornare / rimuovere i parametri di querystring in base all'input degli utenti e prendendo in considerazione l'ancoraggio degli URL.

Non fornire un valore rimuoverà il parametro, fornendo uno aggiungerà / aggiornerà il parametro. Se non viene fornito alcun URL, verrà catturato da window.location

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.

Secondo aggiornamento

Come suggerito da @ JarónBarends - Modifica il valore per verificare se non definito e null per consentire l'impostazione di 0 valori

Terzo aggiornamento

Si è verificato un errore in cui la rimozione di una variabile querystring direttamente prima che un hashtag perdesse il simbolo hashtag che è stato corretto

Quarto aggiornamento

Grazie @rooby per aver sottolineato un'ottimizzazione regex nel primo oggetto RegExp. Imposta regex iniziale su ([? &]) A causa di un problema con l'utilizzo di (\? | &) Trovato da @YonatanKarni

Quinto aggiornamento

Rimozione della dichiarazione di hash var nell'istruzione if / else


5
Il solo controllo della "veridicità" valuecauserà la rimozione di variabili dalla stringa di query quando si imposta il loro valore su 0. quindi, invece di if (value) {}utilizzareif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends

1
Nel RegExp ([? | &]) Dovrebbe essere davvero ([? &])
rooby

Divertente come quello riportato dalla soluzione originale - potrebbe anche usare (\? | &)
ellemayo

1
ottenere un'eccezione "eccezione regolare non valida / gruppo non valido" sulla creazione di regex in Chrome Versione 31.0.1650.63, risolta restituendo l'inizio come "([? &])"
Yonatan Karni,

1
Non che questo importi se non per il fatto che sono OCD, ma la variabile hashviene dichiarata due volte;)
wlingke

117

L' utilità URLSearchParams può essere utile per questo in combinazione con window.location.search. Per esempio:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search);
    searchParams.set("foo", "bar");
    window.location.search = searchParams.toString();
}

Ora fooè stato impostato su barindipendentemente dal fatto che esistesse o meno.

Tuttavia, l'assegnazione di cui sopra window.location.searchcauserà un caricamento della pagina, quindi se ciò non è desiderabile, utilizzare l' API Cronologia come segue:

if ('URLSearchParams' in window) {
    var searchParams = new URLSearchParams(window.location.search)
    searchParams.set("foo", "bar");
    var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString();
    history.pushState(null, '', newRelativePathQuery);
}

Ora non è necessario scrivere la propria regex o la propria logica per gestire la possibile esistenza di stringhe di query.

Tuttavia, il supporto del browser è scarso in quanto è attualmente sperimentale e in uso solo nelle ultime versioni di Chrome, Firefox, Safari, iOS Safari, Android Browser, Android Chrome e Opera. Utilizzare con un polyfill se si decide di usarlo.

Aggiornamento: il supporto del browser è migliorato rispetto alla mia risposta originale.


polly fill, non va bene, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference su ie11 si ottiene quell'errore. non è un pollyfill se non funziona come fallback.
Val

6
Aggiornamento 2019 : il supporto del browser ora è buono per la maggior parte dei browser tranne IE e alcuni browser mobili di piccole dimensioni. Il nuovo pollyfill di ungap copre facilmente questo: github.com/ungap/url-search-params
Flion

Risposta perfetta, tuttavia non gestisce il caso d'uso quando l'hashtag è presente nell'URL. La semplice aggiunta di hash alla fine newRelativePathQueryfa il trucco:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec il

43

Sulla base della risposta di @ amateur (e ora incorporando la correzione dal commento @j_walker_dev), ma tenendo conto del commento sui tag hash nell'URL, utilizzo quanto segue:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if (uri.match(re)) {
    return uri.replace(re, '$1' + key + "=" + value + '$2');
  } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
}

Modificato per risolvere il problema [?|&]con regex che dovrebbe ovviamente essere [?&]come sottolineato nei commenti

Modifica: versione alternativa per supportare anche la rimozione dei parametri URL. Ho usato value === undefinedcome modo per indicare la rimozione. Potrebbe usare value === falseo anche un parametro di input separato come desiderato.

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");
  if( value === undefined ) {
    if (uri.match(re)) {
        return uri.replace(re, '$1$2');
    } else {
        return uri;
    }
  } else {
    if (uri.match(re)) {
        return uri.replace(re, '$1' + key + "=" + value + '$2');
    } else {
    var hash =  '';
    if( uri.indexOf('#') !== -1 ){
        hash = uri.replace(/.*#/, '#');
        uri = uri.replace(/#.*/, '');
    }
    var separator = uri.indexOf('?') !== -1 ? "&" : "?";    
    return uri + separator + key + "=" + value + hash;
  }
  }  
}

Guardalo in azione su https://jsfiddle.net/bp3tmuxh/1/


2
Molto più pulito. Cordiali saluti per gli utenti angolari ui-router che possono avere "?" anche nell'hash. Spostare ilvar separator riga a destra sopra il ritorno risolve un bug con "/ app # / cool? Fun = true". Questo sceglierebbe un "&" come separatore anche se non ci sono ancora parametri di stringhe di query reali. Solo clienti.
j_walker_dev,

3
Come sottolineato nei commenti su altre risposte, [?|&]dovrebbe essere giusto [?&](altrimenti corrisponderà |).
bonger

1
Sì, "([?|&])"non va bene. Si prega di risolvere questo come uno var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");o var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(una bella estensione in altri modi!)
YakovL

ok, scusa, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");non funziona, il secondo funziona
YakovL

Sembra che questa versione non supporti la rimozione di un parametro della stringa di query omettendo il valore. Ho ragione?
jkupczak


12

Mi rendo conto che questa domanda è vecchia ed è stata risolta a morte, ma ecco la mia pugnalata. Sto cercando di reinventare la ruota qui perché stavo usando la risposta attualmente accettata e la cattiva gestione dei frammenti di URL mi ha recentemente morso in un progetto.

La funzione è sotto. È piuttosto lungo, ma è stato realizzato per essere il più resistente possibile. Vorrei suggerimenti per accorciarlo / migliorarlo. Ho messo insieme una piccola suite di test jsFiddle (o altre funzioni simili). Se una funzione può superare tutti i test lì, dico che probabilmente è buono per andare.

Aggiornamento: mi sono imbattuto in una fantastica funzione per l' utilizzo del DOM per analizzare gli URL , quindi ho incorporato questa tecnica qui. Rende la funzione più breve e più affidabile. Puntelli all'autore di quella funzione.

/**
 * Add or update a query string parameter. If no URI is given, we use the current
 * window.location.href value for the URI.
 * 
 * Based on the DOM URL parser described here:
 * http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
 *
 * @param   (string)    uri     Optional: The URI to add or update a parameter in
 * @param   (string)    key     The key to add or update
 * @param   (string)    value   The new value to set for key
 *
 * Tested on Chrome 34, Firefox 29, IE 7 and 11
 */
function update_query_string( uri, key, value ) {

    // Use window URL if no query string is provided
    if ( ! uri ) { uri = window.location.href; }

    // Create a dummy element to parse the URI with
    var a = document.createElement( 'a' ), 

        // match the key, optional square brackets, an equals sign or end of string, the optional value
        reg_ex = new RegExp( key + '((?:\\[[^\\]]*\\])?)(=|$)(.*)' ),

        // Setup some additional variables
        qs,
        qs_len,
        key_found = false;

    // Use the JS API to parse the URI 
    a.href = uri;

    // If the URI doesn't have a query string, add it and return
    if ( ! a.search ) {

        a.search = '?' + key + '=' + value;

        return a.href;
    }

    // Split the query string by ampersands
    qs = a.search.replace( /^\?/, '' ).split( /&(?:amp;)?/ );
    qs_len = qs.length; 

    // Loop through each query string part
    while ( qs_len > 0 ) {

        qs_len--;

        // Remove empty elements to prevent double ampersands
        if ( ! qs[qs_len] ) { qs.splice(qs_len, 1); continue; }

        // Check if the current part matches our key
        if ( reg_ex.test( qs[qs_len] ) ) {

            // Replace the current value
            qs[qs_len] = qs[qs_len].replace( reg_ex, key + '$1' ) + '=' + value;

            key_found = true;
        }
    }   

    // If we haven't replaced any occurrences above, add the new parameter and value
    if ( ! key_found ) { qs.push( key + '=' + value ); }

    // Set the new query string
    a.search = '?' + qs.join( '&' );

    return a.href;
}

2
Questo sembra davvero buono, casi di test solidi + utilizzando il DOM come parser URL. Tuttavia, ho trovato due casi: example.com/?param=val& => example.com/?param=val&&new=key --double & and example.com/team => example.com/team?new=key previsti: team /? new = chiave un reindirizzamento / team? new = chiave per / team / e le query vanno perse.
Timar Ivo Batis,

1
Grazie per il test fallito. Ho aggiornato il violino. Quella prima è dura. Qualche idea su come risolvere la funzione? Il secondo dovrebbe essere gestito senza problemi ed è già coperto nella suite di test. Forse non ti capisco però. Sentiti libero di rovesciare il violino di prova per dimostrare cosa stai vedendo.
Dominic P,

Ho aggiunto alcuni casi di test in cui mi sono imbattuto e soluzioni alternative. Ho provato a usare il DOM il più possibile. In primo luogo avevo bisogno che funzionasse anche per collegamenti relativi all'interno dello stesso dominio. jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis

1
@braed Mi piace l'approccio perché lascia il sollevamento pesante al browser. Come puoi vedere da molte risposte qui, questo problema non è così semplice come sembra. Ci sono MOLTI casi angolari che una soluzione deve coprire. La maggior parte di essi è coperta gratuitamente quando si utilizza il DOM.
Dominic P,

1
@braed sicuramente dai un'occhiata alla suite di test che ho collegato nella risposta. Molte soluzioni qui che non si basano sul DOM falliscono perché non tengono conto di tutti i casi limite elencati. Per quanto riguarda la lettura, potrebbe essere istruttivo guardare il modulo URL per node.js. Non è direttamente correlato, ma ti dà un'idea della complessità implicita nelle stringhe URL.
Dominic P,

11

window.location.search è in lettura / scrittura.

Tuttavia, la modifica della stringa di query reindirizza la pagina in cui ti trovi e provoca un aggiornamento dal server.

Se quello che stai tentando di fare è mantenere lo stato lato client (e potenzialmente renderlo abilitato ai segnalibri), ti consigliamo di modificare l'hash dell'URL invece della stringa di query, che ti mantiene sulla stessa pagina (window.location. l'hash è letto / scritto). Ecco come fanno i siti web come twitter.com.

Avrai anche bisogno del pulsante Indietro per funzionare, dovrai associare eventi javascript all'evento di modifica dell'hash, un buon plugin per questo è http://benalman.com/projects/jquery-hashchange-plugin/


4
Twitter non modifica più l'hash! Hash è morto, benvenuta l' API History !
Alba Mendez,

è tutt'altro che morto. penso che tu stia vivendo in un magico mondo dei sogni in cui la compatibilità del browser legacy non è preoccupante. questo potrebbe essere il tuo caso, ma certamente non è il caso per il resto di noi (o di fatto la maggior parte di noi). forse morire è più appropriato ...
AaronHS,

1
Un anno dopo, sembra che l'unico browser semi-recente che non lo supporta sia IE 9
Douglas.Sesar

11

Se non è impostato o si desidera aggiornare con un nuovo valore, è possibile utilizzare:

window.location.search = 'param=value'; // or param=new_value

Questo è in Javascript semplice, comunque.

MODIFICARE

Potresti provare a utilizzare il plug -in query-object jquery

window.location.search = jQuery.query.set ("param", 5);


1
questo però non manterrà alcun altro parametro della stringa di query sull'URL.
dilettante

hai ragione, mi scuso .. come aggiornamento, ho aggiunto un'altra opzione alla mia risposta :)
tradyblix

Questo non funziona, perché non reimposta un valore. "aggiungi o aggiorna"
Paolo Falomo,

9

Ecco il mio approccio: il location.params() funzione (mostrata sotto) può essere usata come getter o setter. Esempi:

Dato che l'URL è http://example.com/?foo=bar&baz#some-hash,

  1. location.params()restituirà un oggetto con tutti i parametri di ricerca: {foo: 'bar', baz: true}.
  2. location.params('foo')tornerà 'bar'.
  3. location.params({foo: undefined, hello: 'world', test: true})cambierà l'URL in http://example.com/?baz&hello=world&test#some-hash.

Ecco la params()funzione, che può essere facoltativamente assegnata window.locationall'oggetto.

location.params = function(params) {
  var obj = {}, i, parts, len, key, value;

  if (typeof params === 'string') {
    value = location.search.match(new RegExp('[?&]' + params + '=?([^&]*)[&#$]?'));
    return value ? value[1] : undefined;
  }

  var _params = location.search.substr(1).split('&');

  for (i = 0, len = _params.length; i < len; i++) {
    parts = _params[i].split('=');
    if (! parts[0]) {continue;}
    obj[parts[0]] = parts[1] || true;
  }

  if (typeof params !== 'object') {return obj;}

  for (key in params) {
    value = params[key];
    if (typeof value === 'undefined') {
      delete obj[key];
    } else {
      obj[key] = value;
    }
  }

  parts = [];
  for (key in obj) {
    parts.push(key + (obj[key] === true ? '' : '=' + obj[key]));
  }

  location.search = parts.join('&');
};

6

Questa è la mia preferenza e copre i casi che mi vengono in mente. Qualcuno può pensare a un modo per ridurlo a un singolo sostituto?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}

Fallisce anche un bel paio di casi di test da Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis

5

So che questo è piuttosto vecchio ma voglio licenziare la mia versione funzionante qui.

function addOrUpdateUrlParam(uri, paramKey, paramVal) {
  var re = new RegExp("([?&])" + paramKey + "=[^&#]*", "i");
  if (re.test(uri)) {
    uri = uri.replace(re, '$1' + paramKey + "=" + paramVal);
  } else {
    var separator = /\?/.test(uri) ? "&" : "?";
    uri = uri + separator + paramKey + "=" + paramVal;
  }
  return uri;
}

jQuery(document).ready(function($) {
  $('#paramKey,#paramValue').on('change', function() {
    if ($('#paramKey').val() != "" && $('#paramValue').val() != "") {
      $('#uri').val(addOrUpdateUrlParam($('#uri').val(), $('#paramKey').val(), $('#paramValue').val()));
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input style="width:100%" type="text" id="uri" value="http://www.example.com/text.php">
<label style="display:block;">paramKey
  <input type="text" id="paramKey">
</label>
<label style="display:block;">paramValue
  <input type="text" id="paramValue">
</label>

NOTA Questa è una versione modificata di @elreimundo



2

Il mio punto da qui (compatibile con "usa rigoroso"; in realtà non usa jQuery):

function decodeURIParams(query) {
  if (query == null)
    query = window.location.search;
  if (query[0] == '?')
    query = query.substring(1);

  var params = query.split('&');
  var result = {};
  for (var i = 0; i < params.length; i++) {
    var param = params[i];
    var pos = param.indexOf('=');
    if (pos >= 0) {
        var key = decodeURIComponent(param.substring(0, pos));
        var val = decodeURIComponent(param.substring(pos + 1));
        result[key] = val;
    } else {
        var key = decodeURIComponent(param);
        result[key] = true;
    }
  }
  return result;
}

function encodeURIParams(params, addQuestionMark) {
  var pairs = [];
  for (var key in params) if (params.hasOwnProperty(key)) {
    var value = params[key];
    if (value != null) /* matches null and undefined */ {
      pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value))
    }
  }
  if (pairs.length == 0)
    return '';
  return (addQuestionMark ? '?' : '') + pairs.join('&');
}

//// alternative to $.extend if not using jQuery:
// function mergeObjects(destination, source) {
//   for (var key in source) if (source.hasOwnProperty(key)) {
//     destination[key] = source[key];
//   }
//   return destination;
// }

function navigateWithURIParams(newParams) {
  window.location.search = encodeURIParams($.extend(decodeURIParams(), newParams), true);
}

Esempio di utilizzo:

// add/update parameters
navigateWithURIParams({ foo: 'bar', boz: 42 });

// remove parameter
navigateWithURIParams({ foo: null });

// submit the given form by adding/replacing URI parameters (with jQuery)
$('.filter-form').submit(function(e) {
  e.preventDefault();
  navigateWithURIParams(decodeURIParams($(this).serialize()));
});

2

Sulla base della risposta fornita da @ellemayo, ho trovato la seguente soluzione che consente di disabilitare il tag hash, se lo si desidera:

function updateQueryString(key, value, options) {
    if (!options) options = {};

    var url = options.url || location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"), hash;

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

    if ((typeof options.hash === 'undefined' || options.hash) &&
        typeof hash[1] !== 'undefined' && hash[1] !== null)
        url += '#' + hash[1];
    return url;
}

Chiamalo così:

updateQueryString('foo', 'bar', {
    url: 'http://my.example.com#hash',
    hash: false
});

Risultati in:

http://my.example.com?foo=bar

Cavillo stilistico: typeof value !== 'undefined' && value !== nullè più esplicito, ma value != nullsignifica la stessa cosa ed è più conciso.
eppsilon,

2

Ecco una versione più breve che si prende cura di

  • query con o senza un determinato parametro
  • query con più valori di parametro
  • query contenente hash

Codice:

var setQueryParameter = function(uri, key, value) {
  var re = new RegExp("([?&])("+ key + "=)[^&#]*", "g");
  if (uri.match(re)) 
    return uri.replace(re, '$1$2' + value);

  // need to add parameter to URI
  var paramString = (uri.indexOf('?') < 0 ? "?" : "&") + key + "=" + value;
  var hashIndex = uri.indexOf('#');
  if (hashIndex < 0)
    return uri + paramString;
  else
    return uri.substring(0, hashIndex) + paramString + uri.substring(hashIndex);
}

La descrizione di regex può essere trovata qui .

NOTA : questa soluzione si basa sulla risposta @amateur, ma con molti miglioramenti.


2

Codice che aggiunge un elenco di parametri a un URL esistente utilizzando ES6 e jQuery:

class UrlBuilder {
    static appendParametersToUrl(baseUrl, listOfParams) {

        if (jQuery.isEmptyObject(listOfParams)) {
            return baseUrl;
        }

        const newParams = jQuery.param(listOfParams);

        let partsWithHash = baseUrl.split('#');
        let partsWithParams = partsWithHash[0].split('?');

        let previousParams = '?' + ((partsWithParams.length === 2) ? partsWithParams[1] + '&' : '');
        let previousHash = (partsWithHash.length === 2) ? '#' + partsWithHash[1] : '';

        return partsWithParams[0] + previousParams + newParams + previousHash;
    }
}

Dove è listOfParams

const listOfParams = {
    'name_1': 'value_1',
    'name_2': 'value_2',
    'name_N': 'value_N',
};

Esempio di utilizzo:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Test rapidi:

    url = 'http://hello.world';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world

    url = 'http://hello.world#h1';
    console.log('=> ', UrlParameters.appendParametersToUrl(url, null));
    // Output:  http://hello.world#h1

    url = 'http://hello.world';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p1=v1&p2=v2

    url = 'http://hello.world?p0=v0';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2

    url = 'http://hello.world#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
   // Output: http://hello.world?p1=v1&p2=v2#h1

    url = 'http://hello.world?p0=v0#h1';
    params = {'p1': 'v1', 'p2': 'v2'};
    console.log('=> ', UrlParameters.appendParametersToUrl(url, params));
    // Output: http://hello.world?p0=v0&p1=v1&p2=v2#h1

1

Un approccio diverso senza usare espressioni regolari . Supporta ancore 'hash' alla fine dell'URL e caratteri di domanda multipla (?). Dovrebbe essere leggermente più veloce dell'approccio delle espressioni regolari.

function setUrlParameter(url, key, value) {
  var parts = url.split("#", 2), anchor = parts.length > 1 ? "#" + parts[1] : '';
  var query = (url = parts[0]).split("?", 2);
  if (query.length === 1) 
    return url + "?" + key + "=" + value + anchor;

  for (var params = query[query.length - 1].split("&"), i = 0; i < params.length; i++)
    if (params[i].toLowerCase().startsWith(key.toLowerCase() + "="))
      return params[i] = key + "=" + value, query[query.length - 1] = params.join("&"), query.join("?") + anchor;

  return url + "&" + key + "=" + value + anchor
}

1

Utilizzare questa funzione per aggiungere, rimuovere e modificare il parametro della stringa di query dall'URL in base a jquery

/**
@param String url
@param object param {key: value} query parameter
*/
function modifyURLQuery(url, param){
    var value = {};

    var query = String(url).split('?');

    if (query[1]) {
        var part = query[1].split('&');

        for (i = 0; i < part.length; i++) {
            var data = part[i].split('=');

            if (data[0] && data[1]) {
                value[data[0]] = data[1];
            }
        }
    }

    value = $.extend(value, param);

    // Remove empty value
    for (i in value){
        if(!value[i]){
            delete value[i];
        }
    }

    // Return url with modified parameter
    if(value){
        return query[0] + '?' + $.param(value);
    } else {
        return query[0];
    }
}

Aggiungi nuovo e modifica il parametro esistente nell'URL

var new_url = modifyURLQuery("http://google.com?foo=34", {foo: 50, bar: 45});
// Result: http://google.com?foo=50&bar=45

Rimuovi esistente

var new_url = modifyURLQuery("http://google.com?foo=50&bar=45", {bar: null});
// Result: http://google.com?foo=50

1

Usando jQuerypossiamo fare come di seguito

var query_object = $.query_string;
query_object["KEY"] = "VALUE";
var new_url = window.location.pathname + '?'+$.param(query_object)

In variabile new_url avremo nuovi parametri di query.

Riferimento: http://api.jquery.com/jquery.param/


0

Per dare un esempio di codice per la modifica window.location.searchcome suggerito da Gal e tradyblix:

var qs = window.location.search || "?";
var param = key + "=" + value; // remember to URI encode your parameters
if (qs.length > 1) {
    // more than just the question mark, so append with ampersand
    qs = qs + "&";
}
qs = qs + param;
window.location.search = qs;

0

Codice script Java per trovare una stringa di query specifica e sostituirne il valore *

('input.letter').click(function () {
                //0- prepare values
                var qsTargeted = 'letter=' + this.value; //"letter=A";
                var windowUrl = '';
                var qskey = qsTargeted.split('=')[0];
                var qsvalue = qsTargeted.split('=')[1];
                //1- get row url
                var originalURL = window.location.href;
                //2- get query string part, and url
                if (originalURL.split('?').length > 1) //qs is exists
                {
                    windowUrl = originalURL.split('?')[0];
                    var qs = originalURL.split('?')[1];
                    //3- get list of query strings
                    var qsArray = qs.split('&');
                    var flag = false;
                    //4- try to find query string key
                    for (var i = 0; i < qsArray.length; i++) {
                        if (qsArray[i].split('=').length > 0) {
                            if (qskey == qsArray[i].split('=')[0]) {
                                //exists key
                                qsArray[i] = qskey + '=' + qsvalue;
                                flag = true;
                                break;
                            }
                        }
                    }
                    if (!flag)//   //5- if exists modify,else add
                    {
                        qsArray.push(qsTargeted);
                    }
                    var finalQs = qsArray.join('&');
                    //6- prepare final url
                    window.location = windowUrl + '?' + finalQs;
                }
                else {
                    //6- prepare final url
                    //add query string
                    window.location = originalURL + '?' + qsTargeted;
                }
            })
        });

0

Sì, ho avuto un problema in cui la mia querystring sarebbe traboccata e duplicata, ma questo era dovuto alla mia lentezza. così ho giocato un po 'e ho lavorato su js jquery (in realtà sfrigolio) e C # magick.

Quindi mi sono appena reso conto che dopo che il server ha terminato i valori passati, i valori non contano più, non c'è più riutilizzo, se il client volesse fare la stessa cosa evidentemente sarà sempre una nuova richiesta, anche se è il stessi parametri passati. E questo è tutto il lato client, quindi alcuni cache / cookie ecc. Potrebbero essere interessanti in questo senso.

JS:

$(document).ready(function () {
            $('#ser').click(function () {
                SerializeIT();
            });
            function SerializeIT() {
                var baseUrl = "";
                baseUrl = getBaseUrlFromBrowserUrl(window.location.toString());
                var myQueryString = "";
                funkyMethodChangingStuff(); //whatever else before serializing and creating the querystring
                myQueryString = $('#fr2').serialize();
                window.location.replace(baseUrl + "?" + myQueryString);
            }
            function getBaseUrlFromBrowserUrl(szurl) {
                return szurl.split("?")[0];
            } 
            function funkyMethodChangingStuff(){
               //do stuff to whatever is in fr2
            }
        });

HTML:

<div id="fr2">
   <input type="text" name="qURL" value="http://somewhere.com" />
   <input type="text" name="qSPart" value="someSearchPattern" />
</div>
<button id="ser">Serialize! and go play with the server.</button>

C #:

    using System.Web;
    using System.Text;
    using System.Collections.Specialized;

    public partial class SomeCoolWebApp : System.Web.UI.Page
    {
        string weburl = string.Empty;
        string partName = string.Empty;

        protected void Page_Load(object sender, EventArgs e)
        {
            string loadurl = HttpContext.Current.Request.RawUrl;
            string querySZ = null;
            int isQuery = loadurl.IndexOf('?');
            if (isQuery == -1) { 
                //If There Was no Query
            }
            else if (isQuery >= 1) {
                querySZ = (isQuery < loadurl.Length - 1) ? loadurl.Substring(isQuery + 1) : string.Empty;
                string[] getSingleQuery = querySZ.Split('?');
                querySZ = getSingleQuery[0];

                NameValueCollection qs = null;
                qs = HttpUtility.ParseQueryString(querySZ);

                weburl = qs["qURL"];
                partName = qs["qSPart"];
                //call some great method thisPageRocks(weburl,partName); or whatever.
          }
      }
  }

Va bene la critica è benvenuta (questa è stata una mistura notturna quindi sentitevi liberi di annotare gli aggiustamenti). Se questo ha aiutato affatto, sfoglialo, Happy Coding.

Nessun duplicato, ogni richiesta è unica come la hai modificata e, grazie alla sua struttura, è facile aggiungere dinamicamente più query dal dominio.


0

Ecco un metodo alternativo che utilizza le proprietà integrate dell'elemento anchor HTML:

  • Gestisce parametri multivalore.
  • Nessun rischio di modificare il frammento # o qualsiasi cosa diversa dalla stringa di query stessa.
  • Potrebbe essere un po 'più facile da leggere? Ma è più lungo.

    var a = document.createElement('a'),

	getHrefWithUpdatedQueryString = function(param, value) {
	    return updatedQueryString(window.location.href, param, value);
	},

	updatedQueryString = function(url, param, value) {
	    /*
	     A function which modifies the query string 
             by setting one parameter to a single value.

	     Any other instances of parameter will be removed/replaced.
	     */
	    var fragment = encodeURIComponent(param) + 
                           '=' + encodeURIComponent(value);

	    a.href = url;

	    if (a.search.length === 0) {
		a.search = '?' + fragment;
	    } else {
		var didReplace = false,
		    // Remove leading '?'
		    parts = a.search.substring(1)
		// Break into pieces
			.split('&'),

		    reassemble = [],
		    len = parts.length;

		for (var i = 0; i < len; i++) {
		    
		    var pieces = parts[i].split('=');
		    if (pieces[0] === param) {
			if (!didReplace) {
			    reassemble.push('&' + fragment);
			    didReplace = true;
			}
		    } else {
			reassemble.push(parts[i]);
		    }
		}

		if (!didReplace) {
		    reassemble.push('&' + fragment);
		}

		a.search = reassemble.join('&');
	    }

	    return a.href;
	};


0

se si desidera impostare più parametri contemporaneamente:

function updateQueryStringParameters(uri, params) {
    for(key in params){
      var value = params[key],
          re = new RegExp("([?&])" + key + "=.*?(&|$)", "i"),
          separator = uri.indexOf('?') !== -1 ? "&" : "?";
      if (uri.match(re)) {
        uri = uri.replace(re, '$1' + key + "=" + value + '$2');
      }
      else {
        uri = uri + separator + key + "=" + value;
      }
    }
    return uri;
}

stessa funzione di @ amateur

se jslint ti dà un errore, aggiungilo dopo il ciclo for

if(params.hasOwnProperty(key))

Non gestisce gli hash o i parametri a cui non è stato assegnato un valore ( http://abc.def/?a&b&c).
Adam Leggett,

0

Ci sono molte risposte imbarazzanti e inutilmente complicate in questa pagina. Il più votato, @ amateur's, è abbastanza buono, anche se ha un po 'di lanugine non necessaria nel RegExp. Ecco una soluzione leggermente più ottimale con RegExp più pulito e una replacechiamata più pulita :

function updateQueryStringParamsNoHash(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&]*", "i");
  return re.test(uri)
       ? uri.replace(re, '$1' + key + "=" + value)
       : uri + separator + key + "=" + value
  ;
}

Come bonus aggiuntivo, se urinon è una stringa, non otterrai errori nel tentativo di chiamare matcho replacesu qualcosa che potrebbe non implementare tali metodi.

E se vuoi gestire il caso di un hash (e hai già fatto un controllo per HTML formattato correttamente), puoi sfruttare la funzione esistente invece di scrivere una nuova funzione contenente la stessa logica:

function updateQueryStringParams(url, key, value) {
    var splitURL = url.split('#');
    var hash = splitURL[1];
    var uri = updateQueryStringParamsNoHash(splitURL[0]);
    return hash == null ? uri : uri + '#' + hash;
}

Oppure puoi apportare alcune lievi modifiche alla risposta altrimenti eccellente di @ Adam:

function updateQueryStringParameter(uri, key, value) {
  var re = new RegExp("([?&])" + key + "=[^&#]*", "i");
  if (re.test(uri)) {
    return uri.replace(re, '$1' + key + "=" + value);
  } else {
    var matchData = uri.match(/^([^#]*)(#.*)?$/);
    var separator = /\?/.test(uri) ? "&" : "?";    
    return matchData[0] + separator + key + "=" + value + (matchData[1] || '');
  }
}

2
Questa è una parentesi mancante nell'ultima funzione: var matchData = uri.match (/^([^#[*)(#.*)?$/
Jammer

separatornon è definito in updateQueryStringParamsNoHash. In updateQueryStringParameter, tutto si interrompe se al parametro che si sta sostituendo non viene assegnato un valore (ad esempio http://abc.def/?a&b&c).
Adam Leggett,

0

Questo dovrebbe servire allo scopo:

function updateQueryString(url, key, value) {
    var arr =  url.split("#");
    var url = arr[0];
    var fragmentId = arr[1];
    var updatedQS = "";
    if (url.indexOf("?") == -1) {
        updatedQS = encodeURIComponent(key) + "=" + encodeURIComponent(value);
    }
    else {
        updatedQS = addOrModifyQS(url.substring(url.indexOf("?") + 1), key, value); 
    }
    url = url.substring(0, url.indexOf("?")) + "?" + updatedQS;
    if (typeof fragmentId !== 'undefined') {
        url = url + "#" + fragmentId;
    }
    return url;
}

function addOrModifyQS(queryStrings, key, value) {
    var oldQueryStrings = queryStrings.split("&");
    var newQueryStrings = new Array();
    var isNewKey = true;
    for (var i in oldQueryStrings) {
        var currItem = oldQueryStrings[i];
        var searchKey = key + "=";
        if (currItem.indexOf(searchKey) != -1) {
            currItem = encodeURIComponent(key) + "=" + encodeURIComponent(value);
            isNewKey = false;
        }
        newQueryStrings.push(currItem);
    }
    if (isNewKey) {
        newQueryStrings.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
    }
    return newQueryStrings.join("&");
}   
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.