Ajout d'un paramètre à l'URL avec JavaScript

276

Dans une application Web qui utilise des appels AJAX, je dois soumettre une demande mais ajouter un paramètre à la fin de l'URL, par exemple:

URL d'origine:

http: //server/myapp.php? id = 10

URL résultante:

http: //server/myapp.php? id = 10 & enabled = true

Recherche d'une fonction JavaScript qui analyse l'URL en regardant chaque paramètre, puis ajoute le nouveau paramètre ou met à jour la valeur si elle existe déjà.

Lessan Vaezi
la source
Avez-vous recherché des analyseurs d'url javascript ? Vous pouvez créer le vôtre, en divisant chaque caractère &, mais il est probablement plus facile d'utiliser le code existant.
csl
1
J'ai eu un scénario similaire une fois et j'ai trouvé cet article de Peter Bromberg très utile:
Cerebrus
2
window.history.pushState ('page2', 'Title', document.location + '/ page2.php'); fera votre travail sans charger la page
Rutunj sheladiya
1
Cette question a de meilleures réponses ici stackoverflow.com/questions/6953944/…
rkb
incroyable ce n'est pas natif dans cette langue pauvre qu'est JS ....
bohr

Réponses:

192

Une implémentation de base que vous devrez adapter ressemblerait à ceci:

function insertParam(key, value) {
    key = encodeURIComponent(key);
    value = encodeURIComponent(value);

    // kvp looks like ['key1=value1', 'key2=value2', ...]
    var kvp = document.location.search.substr(1).split('&');
    let i=0;

    for(; i<kvp.length; i++){
        if (kvp[i].startsWith(key + '=')) {
            let pair = kvp[i].split('=');
            pair[1] = value;
            kvp[i] = pair.join('=');
            break;
        }
    }

    if(i >= kvp.length){
        kvp[kvp.length] = [key,value].join('=');
    }

    // can return this or...
    let params = kvp.join('&');

    // reload page with new params
    document.location.search = params;
}

C'est environ deux fois plus rapide qu'une regex ou une solution basée sur la recherche, mais cela dépend complètement de la longueur de la chaîne de requête et de l'index de toute correspondance


la méthode des regex lents que j'ai comparée par souci de fin (environ + 150% plus lent)

function insertParam2(key,value)
{
    key = encodeURIComponent(key); value = encodeURIComponent(value);

    var s = document.location.search;
    var kvp = key+"="+value;

    var r = new RegExp("(&|\\?)"+key+"=[^\&]*");

    s = s.replace(r,"$1"+kvp);

    if(!RegExp.$1) {s += (s.length>0 ? '&' : '?') + kvp;};

    //again, do what you will here
    document.location.search = s;
}
annakata
la source
2
Merci encore. voir lessanvaezi.com/wp-content/uploads/2009/01/test.html pour une comparaison de base des méthodes
Lessan Vaezi
16
L'utilisation de escape () pour échapper aux paramètres d'URL est incorrecte. Il rompt pour les valeurs avec "+" en eux. Vous devez plutôt utiliser encodeURIComponent. Discussion complète: xkr.us/articles/javascript/encode-compare
Antonin Hildebrand
4
J'appelle cette fonction et la page se recharge en boucle infinie. Aidez-moi!
2011
6
quand aucun paramètre n'est déjà dans l'url, vous obtenez une valeur? & param =
Roy Toledo
9
Ne devriez-vous pas utiliser encodeURIComponentplutôt que encodeURI? Sinon , tous les personnages comme =, &en votre nom ou valeur corrompra l'URI.
Adrian Pronk
271

Vous pouvez utiliser l'un d'entre eux:

Exemple:

var url = new URL("http://foo.bar/?x=1&y=2");

// If your expected result is "http://foo.bar/?x=1&y=2&x=42"
url.searchParams.append('x', 42);

// If your expected result is "http://foo.bar/?x=42&y=2"
url.searchParams.set('x', 42);
Vianney Bajart
la source
2
Je voudrais ajouter un paramètre de requête sans valeur, par exemple en ajoutant XMLà http://foo.bar/?x=1&y=2pour que le résultat final soit http://foo.bar/?x=1&y=2&XML. Est-ce possible? J'ai essayé url.searchParams.set('XML');, url.searchParams.set('XML', null);et url.searchParams.set('XML', undefined);- mais aucun travaillé dans Chrome 63 .
Abdull
2
Merci! Dommage qu'il ne soit pas encore supporté par iOS. developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
kanji
27
Dommage IE ne le supporte pas.
spedy
3
iOS prend désormais en charge URLSearchParams (depuis 9 jours après le commentaire de @ kanji)
MJeffryes
8
Bonne nouvelle @MJeffryes! Toujours pas pris en charge par IE et Netscape.
Vianney Bajart
64

Merci à tous pour votre contribution. J'ai utilisé du code annakata et modifié pour inclure également le cas où il n'y a aucune chaîne de requête dans l'URL. J'espère que cela vous aidera.

function insertParam(key, value) {
        key = escape(key); value = escape(value);

        var kvp = document.location.search.substr(1).split('&');
        if (kvp == '') {
            document.location.search = '?' + key + '=' + value;
        }
        else {

            var i = kvp.length; var x; while (i--) {
                x = kvp[i].split('=');

                if (x[0] == key) {
                    x[1] = value;
                    kvp[i] = x.join('=');
                    break;
                }
            }

            if (i < 0) { kvp[kvp.length] = [key, value].join('='); }

            //this will reload the page, it's likely better to store this until finished
            document.location.search = kvp.join('&');
        }
    }
Mehdi
la source
3
Il serait préférable de changer de escape(key)et escape(value)à la encodeURIComponentfonction.
kolobok
5
cela devrait-il réellement vérifier if (kvp.length==1 && kvp[0]="")?
Charles L.
@CharlesL. est mieuxif (document.location.search)
Lyubimov Roman
58

C'est une solution très simple. Il ne contrôle pas l'existence des paramètres et ne modifie pas la valeur existante. Il ajoute votre paramètre à la fin, afin que vous puissiez obtenir la dernière valeur dans votre code principal.

function addParameterToURL(param){
    _url = location.href;
    _url += (_url.split('?')[1] ? '&':'?') + param;
    return _url;
}
Mehmet Fatih Yıldız
la source
6
vous devriez également prendre en compte "#" dans l'url .. voici un peu de code:url = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+part+"&"+url.split("?")[1] : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+part+"#"+ url.split("#")[1] : url+'?'+part));
kanzure
2
@kanzure cette chose a l'air diabolique comme l'enfer, mais c'est exactement ce que je voulais. Merci.
Chad von Nau
pourquoi diviser l'url pour vérifier l'existence d'un seul caractère? n'oubliez pas non plus de coder ... quelque chose de plusfunction appendQs(url, key, value) { return url + (url.indexOf('?') >= 0 ? "&" : '?') + encodeURIComponent(key) + "=" + encodeURIComponent(value); };
drzaus
1
Répare le. Cette fonction ne vérifie pas si le paramètre est déjà fourni. J'ai testé et obtenu https://localhost/preview/inventory.html?sortci=priceASC&sortci=priceASC&sortci=stitle.
Jay
@Jay, pourquoi a-t-il besoin d'être réparé? Vérifiez vos hypothèses. Les paramètres de chaîne de requête en double sont autorisés, tout comme les champs de formulaire en double. C'est ainsi que les listes de cases à cocher sont implémentées en HTML et celles-ci seront transmises via la chaîne de requête si la méthode du formulaire = get.
stephen
34

Voici une version largement simplifiée, faisant des compromis pour la lisibilité et moins de lignes de code au lieu de performances micro-optimisées (et nous parlons d'une différence de quelques millisecondes, de manière réaliste ... en raison de la nature de cela (opérant sur l'emplacement du document actuel) ), cela sera très probablement exécuté une fois sur une page).

/**
* Add a URL parameter (or changing it if it already exists)
* @param {search} string  this is typically document.location.search
* @param {key}    string  the key to set
* @param {val}    string  value 
*/
var addUrlParam = function(search, key, val){
  var newParam = key + '=' + val,
      params = '?' + newParam;

  // If the "search" string exists, then build params from it
  if (search) {
    // Try to replace an existance instance
    params = search.replace(new RegExp('([?&])' + key + '[^&]*'), '$1' + newParam);

    // If nothing was replaced, then add the new param to the end
    if (params === search) {
      params += '&' + newParam;
    }
  }

  return params;
};

Vous utiliseriez alors ceci comme ceci:

document.location.pathname + addUrlParam(document.location.search, 'foo', 'bar');
Garrett
la source
1
+1 J'aime la façon dont vous pouvez spécifier autre chose que document.location.search
Muhd
1
+1 Génial, je suis d'accord que la lisibilité est plus importante que la micro-optimisation dans ce cas et je suis heureux de voir que quelqu'un a adopté cette approche. @Muhd Peut-être que c'était un bug dans le moteur JS lorsque vous avez écrit ce commentaire, mais je viens de tester '$ 1' dans ce contexte et cela fonctionne très bien.
JMTyler
Merci beaucoup pour la solution, bien que je sois également bloqué si je veux remplacer une valeur et qu'il y a déjà un paramètre. Au lieu de cela, il écrit 1 $
Codebryo
2
Garrett: Pourriez-vous corriger votre réponse afin qu'elle remplace correctement les paramètres existants? C'est juste une question de remplacement [\?&]par ([\?&])dans le RegExp (je le modifierais moi-même mais je ne sais pas si la politique de la communauté permet de corriger les bugs dans les réponses).
opyh
Cela ne fonctionne pas avec une URL comme " domain.tld ", son ajout "&" au lieu de "?"
user706420
20

/**
* Add a URL parameter 
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var a = document.createElement('a');
   param += (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   a.search += (a.search ? "&" : "") + param;
   return a.href;
}

/**
* Add a URL parameter (or modify if already exists)
* @param {string} url 
* @param {string} param the key to set
* @param {string} value 
*/
var addOrReplaceParam = function(url, param, value) {
   param = encodeURIComponent(param);
   var r = "([&?]|&amp;)" + param + "\\b(?:=(?:[^&#]*))*";
   var a = document.createElement('a');
   var regex = new RegExp(r);
   var str = param + (value ? "=" + encodeURIComponent(value) : ""); 
   a.href = url;
   var q = a.search.replace(regex, "$1"+str);
   if (q === a.search) {
      a.search += (a.search ? "&" : "") + str;
   } else {
      a.search = q;
   }
   return a.href;
}

url = "http://www.example.com#hashme";
newurl = addParam(url, "ciao", "1");
alert(newurl);

Et veuillez noter que les paramètres doivent être encodés avant d'être ajoutés dans la chaîne de requête.

http://jsfiddle.net/48z7z4kx/

Liberté
la source
Petite fuite de mémoire - vous voudrez supprimer l'élément d'ancrage qui a été ajouté au document avant de revenir.
chanvre
@freedev, Non, je ne suis pas sûr. ;) J'ai du mal à trouver une source faisant autorité mais les preuves suggèrent que vous avez raison. Étant donné que l'élément créé n'est jamais attaché au DOM, il doit être nettoyé une fois que la variable est hors de portée. L'API DOM n'est pas particulièrement bien conçue en ce qui concerne les effets secondaires, donc je suis trop prudent.
chanvre
Cette solution ajoute une barre oblique de fin aux URL qui n'ont pas de chemin d'accès et réorganise les paramètres, qui sont des modifications inutiles et éventuellement indésirables. Il ajoute également plutôt que de remplacer les paramètres existants qui n'ont aucune valeur (par exemple http://abc.def/?a&b&b).
Adam Leggett
@AdamLeggett Merci d'avoir signalé le bug qui se produit lorsqu'un paramètre de requête n'a pas de valeur, je viens de corriger ma réponse. Les comportements étranges restants dont vous parlez, si vous avez raison, sont générés par un objet d'ancrage HTML qui est généralement un composant de navigateur standard. Je suggère de revérifier car très peu probable qu'un navigateur ajoute des comportements inutiles ou indésirables.
freedev
1
Le but de la fonction addParam est en effet d'ajouter plusieurs fois un paramètre, et peut-être devriez-vous savoir que vous pouvez passer le même paramètre même avec plusieurs fois la même valeur. stackoverflow.com/questions/24059773/…
freedev
20
const urlParams = new URLSearchParams(window.location.search);

urlParams.set('order', 'date');

window.location.search = urlParams;

.set premier agrément est la clé, le second est la valeur.

Zoidbergseasharp
la source
1
J'adore la simplicité de cela et le fait qu'il utilise des méthodes de navigateur natives
Juan Solano
2
Ceci est la bonne réponse et devrait être voté en tête. Cette nouvelle API est l'ultime pour le traitement des URL
Anthony
19

J'ai une «classe» qui fait ça et la voici:

function QS(){
    this.qs = {};
    var s = location.search.replace( /^\?|#.*$/g, '' );
    if( s ) {
        var qsParts = s.split('&');
        var i, nv;
        for (i = 0; i < qsParts.length; i++) {
            nv = qsParts[i].split('=');
            this.qs[nv[0]] = nv[1];
        }
    }
}

QS.prototype.add = function( name, value ) {
    if( arguments.length == 1 && arguments[0].constructor == Object ) {
        this.addMany( arguments[0] );
        return;
    }
    this.qs[name] = value;
}

QS.prototype.addMany = function( newValues ) {
    for( nv in newValues ) {
        this.qs[nv] = newValues[nv];
    }
}

QS.prototype.remove = function( name ) {
    if( arguments.length == 1 && arguments[0].constructor == Array ) {
        this.removeMany( arguments[0] );
        return;
    }
    delete this.qs[name];
}

QS.prototype.removeMany = function( deleteNames ) {
    var i;
    for( i = 0; i < deleteNames.length; i++ ) {
        delete this.qs[deleteNames[i]];
    }
}

QS.prototype.getQueryString = function() {
    var nv, q = [];
    for( nv in this.qs ) {
        q[q.length] = nv+'='+this.qs[nv];
    }
    return q.join( '&' );
}

QS.prototype.toString = QS.prototype.getQueryString;

//examples
//instantiation
var qs = new QS;
alert( qs );

//add a sinle name/value
qs.add( 'new', 'true' );
alert( qs );

//add multiple key/values
qs.add( { x: 'X', y: 'Y' } );
alert( qs );

//remove single key
qs.remove( 'new' )
alert( qs );

//remove multiple keys
qs.remove( ['x', 'bogus'] )
alert( qs );

J'ai surchargé la méthode toString, donc il n'est pas nécessaire d'appeler QS :: getQueryString, vous pouvez utiliser QS :: toString ou, comme je l'ai fait dans les exemples, simplement compter sur l'objet contraint dans une chaîne.

meouw
la source
8

Si vous avez une chaîne avec une URL que vous souhaitez décorer avec un paramètre, vous pouvez essayer ceci:

urlstring += ( urlstring.match( /[\?]/g ) ? '&' : '?' ) + 'param=value';

Ça veut dire ça ? sera le préfixe du paramètre, mais si vous l'avez déjà fait ? dans urlstring, que & sera le préfixe.

Je recommanderais également de le faire encodeURI( paramvariable )si vous n'avez pas de paramètre codé en dur, mais il se trouve à l'intérieur d'un paramvariable; ou si vous avez des personnages amusants.

Voir Encodage d'URL javascript pour l'utilisation de la encodeURIfonction.

Sasa
la source
7

C'est un moyen simple d'ajouter un paramètre de requête:

const query = new URLSearchParams(window.location.search);
query.append("enabled", "true");

Et c'est plus ici .

Veuillez noter les spécifications de support .

T04435
la source
4
Il semble que cela ne soit pris en charge dans aucune version d'Internet Explorer
MAXE
Idéal pour mobile. Lorsque Internet Explorer apparaît sur mon appareil mobile, je le jette. :-)
stillatmylinux
@MAXE vous avez raison IE / EDGE ne supporte pas beaucoup. Pris en charge
T04435
6

Consultez https://github.com/derek-watson/jsUri

Manipulation de l'URI et de la chaîne de requête en javascript.

Ce projet intègre l'excellente bibliothèque d'expressions régulières parseUri de Steven Levithan. Vous pouvez analyser en toute sécurité des URL de toutes formes et tailles, aussi invalides ou hideuses soient-elles.

Charlie Liang Yuan
la source
404 - L'URL demandée / p / jsuri / est introuvable sur ce serveur. C'est tout ce que nous savons.
Aligma
1
On dirait qu'il a été déplacé. J'ai mis à jour l'URL. Bonne chance!
Charlie Liang Yuan,
Veuillez inclure les détails pertinents dans votre réponse, pas seulement un lien.
jhpratt GOFUNDME RELICENSING
6

Parfois, nous voyons ?à la fin de l'URL, j'ai trouvé des solutions qui génèrent des résultats file.php?&foo=bar. je suis venu avec ma propre solution fonctionne parfaitement comme je veux!

location.origin + location.pathname + location.search + (location.search=='' ? '?' : '&') + 'lang=ar'

Remarque: location.origin ne fonctionne pas dans IE, voici sa correction .

Mr.Shan0
la source
6

La fonction suivante vous aidera à ajouter, mettre à jour et supprimer des paramètres vers ou depuis l'URL.

// exemple1et

var myURL = '/search';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search

// exemple2

var myURL = '/search?category=mobile';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?category=mobile&location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?category=mobile&location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search?category=mobile

// exemple3

var myURL = '/search?location=texas';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search

// exemple4

var myURL = '/search?category=mobile&location=texas';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?category=mobile&location=california

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?category=mobile&location=new%20york

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search?category=mobile

// exemple5

var myURL = 'https://example.com/search?location=texas#fragment';

myURL = updateUrl(myURL,'location','california');
console.log('added location...' + myURL);
//added location.../search?location=california#fragment

myURL = updateUrl(myURL,'location','new york');
console.log('updated location...' + myURL);
//updated location.../search?location=new%20york#fragment

myURL = updateUrl(myURL,'location');
console.log('removed location...' + myURL);
//removed location.../search#fragment

Voici la fonction.

function updateUrl(url,key,value){
      if(value!==undefined){
        value = encodeURI(value);
      }
      var hashIndex = url.indexOf("#")|0;
      if (hashIndex === -1) hashIndex = url.length|0;
      var urls = url.substring(0, hashIndex).split('?');
      var baseUrl = urls[0];
      var parameters = '';
      var outPara = {};
      if(urls.length>1){
          parameters = urls[1];
      }
      if(parameters!==''){
        parameters = parameters.split('&');
        for(k in parameters){
          var keyVal = parameters[k];
          keyVal = keyVal.split('=');
          var ekey = keyVal[0];
          var evalue = '';
          if(keyVal.length>1){
              evalue = keyVal[1];
          }
          outPara[ekey] = evalue;
        }
      }

      if(value!==undefined){
        outPara[key] = value;
      }else{
        delete outPara[key];
      }
      parameters = [];
      for(var k in outPara){
        parameters.push(k + '=' + outPara[k]);
      }

      var finalUrl = baseUrl;

      if(parameters.length>0){
        finalUrl += '?' + parameters.join('&'); 
      }

      return finalUrl + url.substring(hashIndex); 
  }
lingeshram
la source
5

C'était ma propre tentative, mais je vais utiliser la réponse d'Annakata car elle semble beaucoup plus propre:

function AddUrlParameter(sourceUrl, parameterName, parameterValue, replaceDuplicates)
{
    if ((sourceUrl == null) || (sourceUrl.length == 0)) sourceUrl = document.location.href;
    var urlParts = sourceUrl.split("?");
    var newQueryString = "";
    if (urlParts.length > 1)
    {
        var parameters = urlParts[1].split("&");
        for (var i=0; (i < parameters.length); i++)
        {
            var parameterParts = parameters[i].split("=");
            if (!(replaceDuplicates && parameterParts[0] == parameterName))
            {
                if (newQueryString == "")
                    newQueryString = "?";
                else
                    newQueryString += "&";
                newQueryString += parameterParts[0] + "=" + parameterParts[1];
            }
        }
    }
    if (newQueryString == "")
        newQueryString = "?";
    else
        newQueryString += "&";
    newQueryString += parameterName + "=" + parameterValue;

    return urlParts[0] + newQueryString;
}

De plus, j'ai trouvé ce plugin jQuery dans un autre article sur stackoverflow, et si vous avez besoin de plus de flexibilité, vous pouvez l'utiliser: http://plugins.jquery.com/project/query-object

Je pense que le code serait (n'a pas été testé):

return $.query.parse(sourceUrl).set(parameterName, parameterValue).toString();
Lessan Vaezi
la source
Merci d'avoir partagé votre code, Lessan. J'utilise ceci et cela a très bien fonctionné! J'ai téléchargé un résumé de ma propre version, modifié pour être un peu plus succinct et passer la validation JSHint. gist.github.com/jonathanconway/02a183920506acd9890a
Jonathan
3

Ajout à la réponse de @ Vianney https://stackoverflow.com/a/44160941/6609678

Nous pouvons importer le module URL intégré dans le nœud comme suit

const { URL } = require('url');

Exemple:

Terminal $ node
> const { URL } = require('url');
undefined
> let url = new URL('', 'http://localhost:1989/v3/orders');
undefined
> url.href
'http://localhost:1989/v3/orders'
> let fetchAll=true, timePeriod = 30, b2b=false;
undefined
> url.href
'http://localhost:1989/v3/orders'
>  url.searchParams.append('fetchAll', fetchAll);
undefined
>  url.searchParams.append('timePeriod', timePeriod);
undefined
>  url.searchParams.append('b2b', b2b);
undefined
> url.href
'http://localhost:1989/v3/orders?fetchAll=true&timePeriod=30&b2b=false'
> url.toString()
'http://localhost:1989/v3/orders?fetchAll=true&timePeriod=30&b2b=false'

Liens utiles:

https://developer.mozilla.org/en-US/docs/Web/API/URL https://developer.mozilla.org/en/docs/Web/API/URLSearchParams

Albatros de Jinxer
la source
3

Essaye ça.

// uses the URL class
function setParam(key, value) {
            let url = new URL(window.document.location);
            let params = new URLSearchParams(url.search.slice(1));

            if (params.has(key)) {
                params.set(key, value);
            }else {
                params.append(key, value);
            }
        }
Matěj Husák
la source
url.searchParamsest la liste des paramètres pré-initialisés pour cet URLobjet.
amphétamachine
2

J'aime la réponse de Mehmet Fatih Yıldız même s'il n'a pas répondu à toute la question.

Dans la même ligne que sa réponse, j'utilise ce code:

"Il ne contrôle pas l'existence des paramètres et ne modifie pas la valeur existante. Il ajoute votre paramètre à la fin"

  /** add a parameter at the end of the URL. Manage '?'/'&', but not the existing parameters.
   *  does escape the value (but not the key)
   */
  function addParameterToURL(_url,_key,_value){
      var param = _key+'='+escape(_value);

      var sep = '&';
      if (_url.indexOf('?') < 0) {
        sep = '?';
      } else {
        var lastChar=_url.slice(-1);
        if (lastChar == '&') sep='';
        if (lastChar == '?') sep='';
      }
      _url += sep + param;

      return _url;
  }

et le testeur:

  /*
  function addParameterToURL_TESTER_sub(_url,key,value){
    //log(_url);
    log(addParameterToURL(_url,key,value));
  }

  function addParameterToURL_TESTER(){
    log('-------------------');
    var _url ='www.google.com';
    addParameterToURL_TESTER_sub(_url,'key','value');
    addParameterToURL_TESTER_sub(_url,'key','Text Value');
    _url ='www.google.com?';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=B&';
    addParameterToURL_TESTER_sub(_url,'key','value');
    _url ='www.google.com?A=1&B=2';
    addParameterToURL_TESTER_sub(_url,'key','value');

  }//*/
Loda
la source
2

J'irais avec cette petite mais complète bibliothèque pour gérer les URL en js:

https://github.com/Mikhus/jsurl

Joao Leme
la source
Veuillez inclure les détails pertinents dans votre réponse, pas seulement un lien.
jhpratt GOFUNDME RELICENSING
2

C'est ce que j'utilise quand il s'agit de quelques ajouts ou mises à jour de paramètres d'URL de base côté serveur comme Node.js.

CoffeScript:

###
    @method addUrlParam Adds parameter to a given url. If the parameter already exists in the url is being replaced.
    @param {string} url
    @param {string} key Parameter's key
    @param {string} value Parameter's value
    @returns {string} new url containing the parameter
###
addUrlParam = (url, key, value) ->
    newParam = key+"="+value
    result = url.replace(new RegExp('(&|\\?)' + key + '=[^\&|#]*'), '$1' + newParam)
    if result is url
        result = if url.indexOf('?') != -1 then url.split('?')[0] + '?' + newParam + '&' + url.split('?')[1]
    else if url.indexOf('#') != -1 then url.split('#')[0] + '?' + newParam + '#' + url.split('#')[1]
    else url + '?' + newParam
    return result

JavaScript:

function addUrlParam(url, key, value) {
    var newParam = key+"="+value;
    var result = url.replace(new RegExp("(&|\\?)"+key+"=[^\&|#]*"), '$1' + newParam);
    if (result === url) { 
        result = (url.indexOf("?") != -1 ? url.split("?")[0]+"?"+newParam+"&"+url.split("?")[1] 
           : (url.indexOf("#") != -1 ? url.split("#")[0]+"?"+newParam+"#"+ url.split("#")[1] 
              : url+'?'+newParam));
    }
    return result;
}

var url = "http://www.example.com?foo=bar&ciao=3&doom=5#hashme";
result1.innerHTML = addUrlParam(url, "ciao", "1");
<p id="result1"></p>

magicien
la source
2

La solution la plus simple, fonctionne si vous avez déjà une balise ou non, et la supprime automatiquement afin qu'elle ne continue pas à ajouter des balises égales, amusez-vous

function changeURL(tag)
{
if(window.location.href.indexOf("?") > -1) {
    if(window.location.href.indexOf("&"+tag) > -1){

        var url = window.location.href.replace("&"+tag,"")+"&"+tag;
    }
    else
    {
        var url = window.location.href+"&"+tag;
    }
}else{
    if(window.location.href.indexOf("?"+tag) > -1){

        var url = window.location.href.replace("?"+tag,"")+"?"+tag;
    }
    else
    {
        var url = window.location.href+"?"+tag;
    }
}
  window.location = url;
}

PUIS

changeURL("i=updated");
Tombe de Kuza
la source
2

La réponse de Vianney Bajart est correcte; cependant, l' URL ne fonctionnera que si vous avez l'URL complète avec le port, l'hôte, le chemin et la requête:

new URL('http://server/myapp.php?id=10&enabled=true')

Et URLSearchParams ne fonctionnera que si vous passez uniquement la chaîne de requête:

new URLSearchParams('?id=10&enabled=true')

Si vous avez une URL incomplète ou relative et que vous ne vous souciez pas de l'URL de base, vous pouvez simplement vous séparer ?pour obtenir la chaîne de requête et rejoindre plus tard comme ceci:

function setUrlParams(url, key, value) {
  url = url.split('?');
  usp = new URLSearchParams(url[1]);
  usp.set(key, value);
  url[1] = usp.toString();
  return url.join('?');
}

let url = 'myapp.php?id=10';
url = setUrlParams(url, 'enabled', true);  // url = 'myapp.php?id=10&enabled=true'
url = setUrlParams(url, 'id', 11);         // url = 'myapp.php?id=11&enabled=true'

Non compatible avec Internet Explorer.

iau
la source
Si vous utilisez, var u = new URL(window.location), usp = u.searchParams;vous n'avez pas à utiliser de partage de chaîne sophistiqué.
amphetamachine
Bien que votre solution fonctionne pour la plupart des choses, elle modifie l'URL si elle a un point d'interrogation dans une valeur de paramètre:setUrlParams('https://example.com?foo=thing???&bar=baz', 'baz', 'qux') => "https://example.com?foo=thing&baz=qux???&bar=baz"
amphetamachine
1

Si vous vous amusez avec des URL dans des liens ou ailleurs, vous devrez peut-être également prendre en compte le hachage. Voici une solution assez simple à comprendre. Probablement pas le PLUS RAPIDE car il utilise une expression régulière ... mais dans 99,999% des cas, la différence n'a vraiment pas d'importance!

function addQueryParam( url, key, val ){
    var parts = url.match(/([^?#]+)(\?[^#]*)?(\#.*)?/);
    var url = parts[1];
    var qs = parts[2] || '';
    var hash = parts[3] || '';

    if ( !qs ) {
        return url + '?' + key + '=' + encodeURIComponent( val ) + hash;
    } else {
        var qs_parts = qs.substr(1).split("&");
        var i;
        for (i=0;i<qs_parts.length;i++) {
            var qs_pair = qs_parts[i].split("=");
            if ( qs_pair[0] == key ){
                qs_parts[ i ] = key + '=' + encodeURIComponent( val );
                break;
            }
        }
        if ( i == qs_parts.length ){
            qs_parts.push( key + '=' + encodeURIComponent( val ) );
        }
        return url + '?' + qs_parts.join('&') + hash;
    }
}
theozero
la source
Je ne sais pas pourquoi quelqu'un a voté contre. C'est l'une des solutions les plus fiables, bien que ce soit beaucoup plus de code que nécessaire.
Adam Leggett
1

La solution la plus simple à laquelle je peux penser est cette méthode, qui retournera l'URI modifié. J'ai l'impression que la plupart d'entre vous travaillent trop dur.

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

Ok ici je compare deux fonctions, une faite par moi-même (regExp) et une autre faite par (annakata).

Tableau divisé:

function insertParam(key, value)
{
    key = escape(key); value = escape(value);

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

    var i=kvp.length; var x; while(i--) 
    {
        x = kvp[i].split('=');

        if (x[0]==key)
        {
                x[1] = value;
                kvp[i] = x.join('=');
                break;
        }
    }

    if(i<0) {kvp[kvp.length] = [key,value].join('=');}

    //this will reload the page, it's likely better to store this until finished
    return "&"+kvp.join('&'); 
}

Méthode d'expression régulière:

function addParameter(param, value)
{
    var regexp = new RegExp("(\\?|\\&)" + param + "\\=([^\\&]*)(\\&|$)");
    if (regexp.test(document.location.search)) 
        return (document.location.search.toString().replace(regexp, function(a, b, c, d)
        {
                return (b + param + "=" + value + d);
        }));
    else 
        return document.location.search+ param + "=" + value;
}

Cas de test:

time1=(new Date).getTime();
for (var i=0;i<10000;i++)
{
addParameter("test","test");
}
time2=(new Date).getTime();
for (var i=0;i<10000;i++)
{
insertParam("test","test");
}

time3=(new Date).getTime();

console.log((time2-time1)+" "+(time3-time2));

Il semble que même avec la solution la plus simple (lorsque l'expression rationnelle utilise uniquement le test et n'entre pas la fonction .replace), elle est toujours plus lente que le fractionnement ... Eh bien. Regexp est un peu lent mais ... euh ...

Photographie de Paweł Witkowski
la source
comme je l'ai mentionné, c'est en fait relativement lent - et fwiw, document.location.search est plus clair
annakata
0

Voici ce que je fais. En utilisant ma fonction editParams (), vous pouvez ajouter, supprimer ou modifier n'importe quel paramètre, puis utiliser la fonction intégrée replaceState () pour mettre à jour l'URL:

window.history.replaceState('object or string', 'Title', 'page.html' + editParams('enable', 'true'));


// background functions below:

// add/change/remove URL parameter
// use a value of false to remove parameter
// returns a url-style string
function editParams (key, value) {
  key = encodeURI(key);

  var params = getSearchParameters();

  if (Object.keys(params).length === 0) {
    if (value !== false)
      return '?' + key + '=' + encodeURI(value);
    else
      return '';
  }

  if (value !== false)
    params[key] = encodeURI(value);
  else
    delete params[key];

  if (Object.keys(params).length === 0)
    return '';

  return '?' + $.map(params, function (value, key) {
    return key + '=' + value;
  }).join('&');
}

// Get object/associative array of URL parameters
function getSearchParameters () {
  var prmstr = window.location.search.substr(1);
  return prmstr !== null && prmstr !== "" ? transformToAssocArray(prmstr) : {};
}

// convert parameters from url-style string to associative array
function transformToAssocArray (prmstr) {
  var params = {},
      prmarr = prmstr.split("&");

  for (var i = 0; i < prmarr.length; i++) {
    var tmparr = prmarr[i].split("=");
    params[tmparr[0]] = tmparr[1];
  }
  return params;
}
Bobb Fwed
la source
0

Du mieux que je puisse dire, aucune des réponses ci-dessus ne répond au cas où la chaîne de requête contient des paramètres qui sont eux-mêmes un tableau et par conséquent apparaîtront plus d'une fois, par exemple:

http://example.com?sizes[]=a&sizes[]=b

La fonction suivante est ce que j'ai écrit pour mettre à jour document.location.search. Il prend un tableau de tableaux de paires clé / valeur comme argument et il retournera une version révisée de ce dernier avec laquelle vous pourrez faire ce que vous voudrez. Je l'utilise comme ceci:

var newParams = [
    ['test','123'],
    ['best','456'],
    ['sizes[]','XXL']
];
var newUrl = document.location.pathname + insertParams(newParams);
history.replaceState('', '', newUrl);

Si l'URL actuelle était:

http://example.com/index.php?test=replaceme&sizes[]=XL

Cela vous amènerait

http://example.com/index.php?test=123&sizes[]=XL&sizes[]=XXL&best=456

Fonction

function insertParams(params) {
    var result;
    var ii = params.length;
    var queryString = document.location.search.substr(1);
    var kvps = queryString ? queryString.split('&') : [];
    var kvp;
    var skipParams = [];
    var i = kvps.length;
    while (i--) {
        kvp = kvps[i].split('=');
        if (kvp[0].slice(-2) != '[]') {
            var ii = params.length;
            while (ii--) {
                if (params[ii][0] == kvp[0]) {
                    kvp[1] = params[ii][1];
                    kvps[i] = kvp.join('=');
                    skipParams.push(ii);
                }
            }
        }
    }
    var ii = params.length;
    while (ii--) {
        if (skipParams.indexOf(ii) === -1) {
            kvps.push(params[ii].join('='));
        }
    }
    result = kvps.length ? '?' + kvps.join('&') : '';
    return result;
}
billynoah
la source
0

Essayez
Les expressions régulières, si lentes, donc:

var SetParamUrl = function(_k, _v) {// replace and add new parameters

    let arrParams = window.location.search !== '' ? decodeURIComponent(window.location.search.substr(1)).split('&').map(_v => _v.split('=')) : Array();
    let index = arrParams.findIndex((_v) => _v[0] === _k); 
    index = index !== -1 ? index : arrParams.length;
    _v === null ? arrParams = arrParams.filter((_v, _i) => _i != index) : arrParams[index] = [_k, _v];
    let _search = encodeURIComponent(arrParams.map(_v => _v.join('=')).join('&'));

    let newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + (arrParams.length > 0 ? '?' +  _search : ''); 

    // window.location = newurl; //reload 

    if (history.pushState) { // without reload  
        window.history.pushState({path:newurl}, null, newurl);
    }

};

var GetParamUrl = function(_k) {// get parameter by key

    let sPageURL = decodeURIComponent(window.location.search.substr(1)),
        sURLVariables = sPageURL.split('&').map(_v => _v.split('='));
    let _result = sURLVariables.find(_v => _v[0] === _k);
    return _result[1];

};

Exemple:

        // https://some.com/some_path
        GetParamUrl('cat');//undefined
        SetParamUrl('cat', "strData");// https://some.com/some_path?cat=strData
        GetParamUrl('cat');//strData
        SetParamUrl('sotr', "strDataSort");// https://some.com/some_path?cat=strData&sotr=strDataSort
        GetParamUrl('sotr');//strDataSort
        SetParamUrl('cat', "strDataTwo");// https://some.com/some_path?cat=strDataTwo&sotr=strDataSort
        GetParamUrl('cat');//strDataTwo
        //remove param
        SetParamUrl('cat', null);// https://some.com/some_path?sotr=strDataSort
amiron
la source
0

Avec les nouvelles réalisations de JS, voici comment ajouter un paramètre de requête à l'URL:

var protocol = window.location.protocol,
    host = '//' + window.location.host,
    path = window.location.pathname,
    query = window.location.search;

var newUrl = protocol + host + path + query + (query ? '&' : '?') + 'param=1';

window.history.pushState({path:newUrl}, '' , newUrl);

Voir également cette possibilité Moziila URLSearchParams.append ()

Tout est bien
la source
0

Cela fonctionnera dans tous les navigateurs modernes.

function insertParam(key,value) {
      if (history.pushState) {
          var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' +key+'='+value;
          window.history.pushState({path:newurl},'',newurl);
      }
    }
Prasobh.Kollattu
la source
0

Réinitialiser toute la chaîne de requête

var params = { params1:"val1", params2:"val2" };
let str = jQuery.param(params);

let uri = window.location.href.toString();
if (uri.indexOf("?") > 0)
   uri = uri.substring(0, uri.indexOf("?"));

console.log(uri+"?"+str);
//window.location.href = uri+"?"+str;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Bashirpour
la source