Comment puis-je ajouter ou mettre à jour un paramètre de chaîne de requête?

364

Avec javascript, comment puis-je ajouter un paramètre de chaîne de requête à l'URL s'il n'est pas présent ou s'il est présent, mettre à jour la valeur actuelle? J'utilise jquery pour mon développement côté client.

amateur
la source
1
Il semble que j'ai écrit la fonction "parseQueryString" en JavaScript environ 100 fois au cours de ma carrière. C'est pas difficile. Points clés, String#splitprend un deuxième paramètre pour les divisions maximales. jQuery mapsera également utile.
jpsimons
Ce message SO a également de nombreuses solutions stackoverflow.com/questions/1090948/…
Dilip Rajkumar
1
Certaines personnes considèrent que cette question signifie «comment modifier l'URL dans la barre d'adresse» et d'autres «comment modifier une variable d'URL»
PandaWood
doublon possible de stackoverflow.com/questions/486896/…
Utilisateur

Réponses:

468

J'ai écrit la fonction suivante qui accomplit ce que je veux réaliser:

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;
  }
}
amateur
la source
36
Cette réponse ne fonctionne pas lorsqu'il y a un hachage dans l'URI - les chaînes de requête doivent être placées avant le hachage, sinon elles ne sont pas envoyées au serveur. jsfiddle.net/4yXzR
Greg
20
[?|&]devrait être[?&]
soju
8
Limitez la portée de la variable de séparateur à la fonction locale en ajoutant varjuste avant la déclaration de séparateur.
Andrea Salicetti
3
Je pense que vous devriez ajouter value = encodeURIComponent(value);dans la première ligne, sinon les sauts de ligne ne sont pas correctement échappés.
Felix
18
Cela se chargera également du hachage: gist.github.com/niyazpk/f8ac616f181f6042d1e0
Niyaz
189

J'ai étendu la solution et l'ai combinée avec une autre que j'ai trouvée pour remplacer / mettre à jour / supprimer les paramètres de la chaîne de requête en fonction de l'entrée des utilisateurs et en tenant compte de l'ancre des URL.

Ne pas fournir de valeur supprimera le paramètre, en fournir un ajoutera / mettra à jour le paramètre. Si aucune URL n'est fournie, elle sera récupérée à partir de 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;
        }
    }
}

Mise à jour

Il y avait un bug lors de la suppression du premier paramètre dans la chaîne de requête, j'ai retravaillé l'expression régulière et testé pour inclure un correctif.

Deuxième mise à jour

Comme suggéré par @ JarónBarends - Vérifiez la valeur de réglage pour vérifier par rapport à undefined et null pour autoriser la définition de valeurs 0

Troisième mise à jour

Il y avait un bogue où la suppression d'une variable de chaîne de requête directement avant un hashtag perdrait le symbole du hashtag qui a été corrigé

Quatrième mise à jour

Merci à @rooby d'avoir signalé une optimisation d'expression régulière dans le premier objet RegExp. Réglez l'expression régulière sur ([? &]) En raison d'un problème avec l'utilisation de (\? | &) Trouvé par @YonatanKarni

Cinquième mise à jour

Suppression de la déclaration de hachage var dans l'instruction if / else

ellemayo
la source
5
Le simple fait de vérifier la «véracité» de valuececi supprimera les variables de la chaîne de requête lorsque vous définissez leur valeur sur 0. donc au lieu de if (value) {}vous devez utiliserif (typeOf value !== 'undefined' && value !== null) {}
Jarón Barends
1
Dans le RegExp ([? | &])
Devrait
C'est drôle comme cela a été reporté de la solution d'origine - pourrait également utiliser (\? | &)
ellemayo
1
obtenir une exception "exception régulière non valide / groupe non valide" lors de la création de regex dans la version 31.0.1650.63 de chrome, résolue en renvoyant le début à "([? &])"
Yonatan Karni
1
Non pas que cela compte, sauf pour moi étant TOC, mais la variable hashest déclarée deux fois;)
wlingke
117

le utilitaire URLSearchParams peut être utile pour cela en combinaison avec window.location.search. Par exemple:

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

Maintenant, il fooa été défini sur barqu'il existe ou non.

Cependant, l'affectation ci-dessus window.location.searchentraînera un chargement de page, donc si ce n'est pas souhaitable, utilisez le API Historique comme suit:

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

Maintenant, vous n'avez plus besoin d'écrire votre propre expression rationnelle ou logique pour gérer l'existence possible de chaînes de requête.

Cependant, la prise en charge du navigateur est médiocre car elle est actuellement expérimentale et n'est utilisée que dans les versions récentes de Chrome, Firefox, Safari, iOS Safari, navigateur Android, Android Chrome et Opera. À utiliser avec un polyfill si vous décidez de l'utiliser.

Mise à jour: le support du navigateur s'est amélioré depuis ma réponse d'origine.

Anthony Manning-Franklin
la source
remplissage polly, n'est pas bon, Unable to set property '__URLSearchParams__:0.8503766759030615' of undefined or null reference sur ie11 vous obtenez cette erreur. ce n'est pas un pollyfill s'il ne fonctionne pas comme solution de rechange.
Val
6
Mise à jour 2019 : la prise en charge du navigateur est désormais bonne pour la plupart des navigateurs, à l'exception d'IE et de certains petits navigateurs mobiles. Le nouveau pollyfill de ungap couvre facilement cela: github.com/ungap/url-search-params
Flion
Réponse parfaite, cependant, elle ne gère pas le cas où un hashtag est présent dans l'url. Ajout simple de hachage à la fin de newRelativePathQueryl'astuce:var newRelativePathQuery = window.location.pathname + '?' + searchParams.toString() + window.location.hash;
kudlohlavec
43

Basé sur la réponse de @ amateur (et intégrant maintenant le correctif du commentaire @j_walker_dev), mais en tenant compte du commentaire sur les balises de hachage dans l'url, j'utilise ce qui suit:

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

Modifié pour corriger [?|&]en regex qui devrait bien sûr être[?&] comme indiqué dans les commentaires

Modifier: version alternative pour prendre également en charge la suppression des paramètres d'URL. J'ai utilisé value === undefinedcomme moyen d'indiquer la suppression. Pourrait utiliser value === falseou même un paramètre d'entrée séparé comme souhaité.

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

Voyez-le en action sur https://jsfiddle.net/bp3tmuxh/1/

Adam
la source
2
Beaucoup plus propre. FYI pour les utilisateurs de routeur ui angulaire qui peuvent avoir "?" dans le hachage aussi. Déplacer la var separatorligne à droite au-dessus du retour corrige un bug avec "/ app # / cool? Fun = true". Cela choisirait un "&" comme séparateur même s'il n'y a pas encore de paramètres de chaîne de requête réels. Seuls les clients.
j_walker_dev
3
Comme indiqué dans les commentaires sur les autres réponses, [?|&]devrait être juste [?&](sinon cela correspondra |).
bonger
1
Ouais, ce "([?|&])"n'est pas bon. Veuillez corriger cela soit var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");ou var re = new RegExp("([?&])" + key + "=.*?(&|#|$)", "i");(une belle extension à d'autres égards!)
YakovL
ok, désolé, var re = new RegExp("(?|&)" + key + "=.*?(&|#|$)", "i");ne fonctionne pas, le second fonctionne
YakovL
Il semble que cette version ne prenne pas en charge la suppression d'un paramètre de chaîne de requête en omettant la valeur. Ai-je raison?
jkupczak
12

Je me rends compte que cette question est ancienne et qu'il a été répondu à mort, mais voici mon coup de poignard. J'essaie de réinventer la roue ici parce que j'utilisais la réponse actuellement acceptée et la mauvaise gestion des fragments d'URL m'a récemment mordu dans un projet.

La fonction est ci-dessous. C'est assez long, mais il a été conçu pour être aussi résistant que possible. J'adorerais des suggestions pour le raccourcir / l'améliorer. J'ai mis en place une petite suite de tests jsFiddle pour cela (ou d'autres fonctions similaires). Si une fonction peut réussir chacun des tests là-bas, je dis que c'est probablement bien d'y aller.

Mise à jour: je suis tombé sur une fonction intéressante pour utiliser le DOM pour analyser les URL , j'ai donc incorporé cette technique ici. Il rend la fonction plus courte et plus fiable. Accessoires à l'auteur de cette fonction.

/**
 * 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;
}
Dominic P
la source
2
Cela semble vraiment bon, des cas de test solides + en utilisant le DOM comme analyseur d'URL. J'ai cependant trouvé deux cas: example.com/?param=val& => example.com/?param=val&&new=key --double & et example.com/team => example.com/team?new=key attendu: team /? new = key une redirection / team? new = key vers / team / et les requêtes sont perdues.
Timar Ivo Batis
1
Merci pour l'échec du test. J'ai mis à jour le violon. Ce premier est difficile. Des idées sur la façon de corriger la fonction pour cela? La seconde devrait être gérée sans problème et est déjà couverte dans la suite de tests. Peut-être que je ne te comprends pas. N'hésitez pas à bifurquer le violon de test pour montrer ce que vous voyez.
Dominic P
J'ai ajouté des cas de test que j'ai rencontrés et des solutions de contournement. J'ai essayé d'utiliser le DOM autant que possible. Principalement, j'avais besoin de cela pour travailler également pour des liens relatifs dans le même domaine.jsfiddle.net/Timar/7sjrhbm3
Timar Ivo Batis
1
@braed J'aime l'approche car elle laisse la lourde tâche au navigateur. Comme vous le voyez à partir de nombreuses réponses ici, ce problème n'est pas aussi simple qu'il y paraît. Il y a BEAUCOUP de cas d'angle qu'une solution doit couvrir. La plupart d'entre eux sont couverts gratuitement lorsque vous utilisez le DOM.
Dominic P
1
@braed, jetez un coup d'œil à la suite de tests que j'ai liée dans la réponse. Beaucoup de solutions ici qui ne dépendent pas du DOM échouent car elles ne tiennent pas compte de tous les cas marginaux répertoriés. Quant à la lecture, il pourrait être instructif de regarder le module URL pour node.js. Ce n'est pas directement lié, mais cela vous donne une idée de la complexité impliquée dans les chaînes d'URL.
Dominic P
11

window.location.search est en lecture / écriture.

Cependant, la modification de la chaîne de requête redirigera la page sur laquelle vous vous trouvez et provoquera une actualisation à partir du serveur.

Si ce que vous essayez de faire est de maintenir l'état côté client (et de le rendre potentiellement compatible avec les signets), vous voudrez modifier le hachage URL au lieu de la chaîne de requête, ce qui vous maintient sur la même page (window.location. le hachage est en lecture / écriture). C'est ainsi que les sites Web comme twitter.com procèdent.

Vous voudrez également que le bouton de retour fonctionne, vous devrez lier les événements javascript à l'événement de changement de hachage, un bon plugin pour cela est http://benalman.com/projects/jquery-hashchange-plugin/

Fille
la source
4
Twitter ne modifie plus le hachage! Hash est mort, bienvenue à l' API Historique !
Alba Mendez
c'est loin d'être mort. Je pense que vous vivez dans un pays de rêve magique où la compatibilité avec les anciens navigateurs n'est pas un problème. cela peut être le cas pour vous, mais ce n'est certainement pas le cas pour le reste d'entre nous (ou en fait la majorité d'entre nous). peut-être que mourir est plus approprié ...
AaronHS
1
Un an plus tard, il semble que le seul navigateur semi-récent qui ne le supporte pas soit IE 9
Douglas.Sesar
11

S'il n'est pas défini ou si vous souhaitez mettre à jour avec une nouvelle valeur, vous pouvez utiliser:

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

C'est en Javascript simple, soit dit en passant.

ÉDITER

Vous voudrez peut-être essayer d'utiliser le plugin jquery query-object

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

tradyblix
la source
1
cela ne conservera cependant aucun autre paramètre de chaîne de requête sur l'url.
amateur
vous avez raison, je m'excuse .. en tant que mise à jour, j'ai ajouté une autre option à ma réponse :)
tradyblix
Cela ne fonctionne pas, car il ne réinitialise pas une valeur. "ajouter ou mettre à jour"
Paolo Falomo
9

Voici mon approche: le location.params() fonction (illustrée ci-dessous) peut être utilisée comme getter ou setter. Exemples:

Étant donné que l'URL est http://example.com/?foo=bar&baz#some-hash,

  1. location.params()retourne un objet avec tous les paramètres de la requête: {foo: 'bar', baz: true}.
  2. location.params('foo')reviendra 'bar'.
  3. location.params({foo: undefined, hello: 'world', test: true})changera l'URL en http://example.com/?baz&hello=world&test#some-hash.

Voici la params()fonction, qui peut éventuellement être affectée à l' window.locationobjet.

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('&');
};
jake
la source
6

C'est ma préférence, et elle couvre les cas auxquels je peux penser. Quelqu'un peut-il penser à un moyen de le réduire à un seul remplacement?

function setParam(uri, key, val) {
    return uri
        .replace(RegExp("([?&]"+key+"(?=[=&#]|$)[^#&]*|(?=#|$))"), "&"+key+"="+encodeURIComponent(val))
        .replace(/^([^?&]+)&/, "$1?");
}
Adam Leggett
la source
Échoue également quelques tests de Dominic P stackoverflow.com/a/23529943/8385841
Timar Ivo Batis
5

Je sais que c'est assez ancien mais je veux lancer ma version de travail ici.

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>

REMARQUE Il s'agit d'une version modifiée de @elreimundo

Paolo Falomo
la source
2

Ma prise d'ici (compatible avec "use strict"; n'utilise pas vraiment 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);
}

Exemple d'utilisation:

// 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()));
});
Andrey Tarantsov
la source
2

Sur la base de la réponse donnée par @ellemayo, j'ai trouvé la solution suivante qui permet de désactiver la balise de hachage si vous le souhaitez:

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

Appelez ça comme ceci:

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

Résulte en:

http://my.example.com?foo=bar
RuubW
la source
Problème stylistique: typeof value !== 'undefined' && value !== nullest plus explicite, mais value != nullsignifie la même chose et est plus concis.
eppsilon
2

Voici une version plus courte qui prend en charge

  • requête avec ou sans paramètre donné
  • requête avec plusieurs valeurs de paramètre
  • requête contenant du hachage

Code:

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 description de l' expression régulière peut être trouvée ici .

REMARQUE : Cette solution est basée sur la réponse @amateur, mais avec de nombreuses améliorations.

MaxZoom
la source
2

Code qui ajoute une liste de paramètres à une URL existante à l'aide d'ES6 et de 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;
    }
}

Où listOfParams est comme

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

Exemple d'utilisation:

    UrlBuilder.appendParametersToUrl(urlBase, listOfParams);

Tests rapides:

    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
Samuel Vicent
la source
1

Une approche différente sans utiliser d'expressions régulières . Prend en charge les ancres de hachage à la fin de l'URL ainsi que plusieurs caractères de point d'interrogation (?). Devrait être légèrement plus rapide que l'approche par expression régulière.

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
}
cwills
la source
1

Utilisez cette fonction pour ajouter, supprimer et modifier le paramètre de chaîne de requête de l'URL basé sur 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];
    }
}

Ajouter un nouveau paramètre et le modifier à l'URL

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

Supprimer l'existant

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

En utilisant, jQuerynous pouvons faire comme ci-dessous

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

En variable new_url nous aurons de nouveaux paramètres de requête.

Référence: http://api.jquery.com/jquery.param/

anjaneyulubatta505
la source
0

Pour donner un exemple de code à modifier window.location.searchcomme suggéré par Gal et 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;
Risadinha
la source
0

Code de script Java pour rechercher une chaîne de requête spécifique et remplacer sa valeur *

('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;
                }
            })
        });
Mohamed.Abdo
la source
0

Oui, j'ai eu un problème où ma chaîne de requête débordait et se dupliquait, mais cela était dû à ma propre lenteur. donc j'ai joué un peu et travaillé sur js jquery (en fait grésillement) et C # magick.

Donc je viens de réaliser qu'après que le serveur a fini avec les valeurs passées, les valeurs n'ont plus d'importance, il n'y a pas de réutilisation, si le client voulait faire la même chose évidemment, ce sera toujours une nouvelle demande, même si c'est la mêmes paramètres étant passés. Et c'est tout côté client, donc certains cache / cookies, etc. pourraient être cool à cet égard.

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

La critique est la bienvenue (c'était une concoction nocturne, alors n'hésitez pas à noter les ajustements). Si cela vous a aidé du tout, faites-le, Happy Coding.

Pas de doublons, chaque demande est aussi unique que vous l'avez modifiée, et en raison de la façon dont celle-ci est structurée, il est facile d'ajouter dynamiquement plus de requêtes depuis le dom.

LokizFenrir
la source
0

Voici une méthode alternative utilisant les propriétés intégrées de l'élément HTML d'ancrage:

  • Gère les paramètres à valeurs multiples.
  • Aucun risque de modifier le fragment # ou autre chose que la chaîne de requête elle-même.
  • Peut-être un peu plus facile à lire? Mais c'est plus long.

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

GlennS
la source
0

si vous souhaitez définir plusieurs paramètres à la fois:

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

même fonction que chez amateur

si jslint vous donne une erreur, ajoutez ceci après la boucle for

if(params.hasOwnProperty(key))
Rachid O
la source
Ne gère pas les hachages ou les paramètres auxquels aucune valeur n'est attribuée ( http://abc.def/?a&b&c).
Adam Leggett
0

Il y a beaucoup de réponses maladroites et inutilement compliquées sur cette page. La note la plus élevée, @ amateur, est assez bonne, bien qu'elle ait un peu de peluches inutiles dans le RegExp. Voici une solution légèrement plus optimale avec un nettoyant RegExp et un replaceappel plus propre :

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

En prime, s'il urine s'agit pas d'une chaîne, vous n'obtiendrez pas d'erreurs en essayant d'appeler matchou replacesur quelque chose qui peut ne pas implémenter ces méthodes.

Et si vous souhaitez gérer le cas d'un hachage (et que vous avez déjà vérifié le format HTML correctement formaté), vous pouvez tirer parti de la fonction existante au lieu d'écrire une nouvelle fonction contenant la même logique:

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

Ou vous pouvez apporter de légères modifications à la réponse par ailleurs excellente de @ 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] || '');
  }
}
elreimundo
la source
2
Il s'agit d'une parenthèse manquante dans la dernière fonction: var matchData = uri.match (/^((^^^^ ))(#
Jammer
separatorn'est pas défini dans updateQueryStringParamsNoHash. Dans updateQueryStringParameter, tout tombe en panne si le paramètre que vous remplacez ne reçoit pas de valeur (par exemple http://abc.def/?a&b&c).
Adam Leggett
0

Cela devrait servir le but:

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("&");
}   
mmuzahid
la source