457 votes

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

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.

1 votes

J'ai l'impression d'avoir écrit la fonction "parseQueryString" en JavaScript une centaine de fois au cours de ma carrière. Ce n'est pas difficile. Les points clés, String#split prend un deuxième paramètre pour les divisions maximales. map sera également utile.

0 votes

Ce post SO propose également de nombreuses solutions stackoverflow.com/questions/1090948/

2 votes

Certains interprètent cette question comme signifiant "comment changer l'URL dans la barre d'adresse" et d'autres "comment changer n'importe quelle variable URL".

518voto

amateur Points 8327

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

43 votes

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

8 votes

Limiter la portée de la variable séparateur à la fonction locale en ajoutant var juste avant la déclaration du séparateur.

2 votes

Sympa ! @greg : vous avez raison - voir ma réponse pour une variante qui devrait gérer les balises de hachage.

196voto

ellemayo Points 1687

J'ai élargi la solution et l'ai combinée avec une autre que j'ai trouvée pour remplacer/modifier/supprimer les paramètres de la chaîne de requête en fonction de la saisie des utilisateurs et en tenant compte de l'ancre des urls.

Ne pas fournir de valeur supprimera le paramètre, en fournir une 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é la regex et le test pour inclure une correction.

Deuxième mise à jour

Comme suggéré par @JarónBarends - Modifier la vérification des valeurs pour qu'elles soient vérifiées par rapport à undefined et null afin de permettre la définition de valeurs 0

Troisième mise à jour

Il y avait un problème où la suppression d'une variable querystring directement avant un hashtag entraînait la perte du symbole de hashtag.

Quatrième mise à jour

Merci @rooby d'avoir signalé une optimisation regex dans le premier objet RegExp. Définir la regex initiale à ([?&]) en raison d'un problème avec l'utilisation de (\?|&) trouvé par @YonatanKarni.

Cinquième mise à jour

Suppression de la déclaration de la variable hash dans l'instruction if/else

5 votes

Je vérifie juste la véracité de value aura pour effet de supprimer les variables de la chaîne de requête lorsque vous fixez leur valeur à 0. Ainsi, au lieu de if (value) {} vous devez utiliser if (typeOf value !== 'undefined' && value !== null) {}

1 votes

Dans le RegExp, ([?|&]) devrait être ([?&]).

0 votes

C'est marrant de voir comment cela a été reporté de la solution originale - on pourrait aussi utiliser (\?|&)

46voto

Adam Points 2623

En me basant sur la réponse de @amateur (et en incorporant maintenant la correction du commentaire de @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;
  }
}

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

Edit : Version alternative pour supporter la suppression des paramètres d'URL également. J'ai utilisé value === undefined comme moyen d'indiquer la suppression. On pourrait utiliser value === false ou même un paramètre d'entrée séparé, selon les besoins.

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 à https://jsfiddle.net/bp3tmuxh/1/

2 votes

Beaucoup plus propre. Pour info, pour les utilisateurs d'angular ui-router qui peuvent avoir " ?" dans le hash également. En déplaçant le var separator à droite au-dessus du retour corrige un bug avec "/app#/cool?fun=true". Cela choisissait un "&" comme séparateur même s'il n'y a pas encore de paramètres de chaîne de requête réels. Seulement ceux du client.

3 votes

Comme l'ont souligné les commentaires sur d'autres réponses, [?|&] devrait être juste [?&] (sinon, il correspondra à | ).

1 votes

Oui, "([?|&])" 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 !)

20voto

Mikhus Points 619

Voici ma bibliothèque pour y parvenir : https://github.com/Mikhus/jsurl

var u = new Url;
u.query.param='value'; // adds or replaces the param
alert(u)

11voto

Gal Points 696

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

Cependant, la modification de la chaîne d'interrogation redirigera la page sur laquelle vous vous trouvez et entraînera une actualisation du serveur.

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

Si vous voulez que le bouton retour fonctionne, vous devez lier des événements javascript à l'événement de changement de hachage. http://benalman.com/projects/jquery-hashchange-plugin/

5 votes

Twitter ne modifie plus les hashs ! Le hash est mort, bienvenue au Histoire API !

0 votes

Il 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. c'est 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 en train de mourir est plus approprié...

1 votes

Un an plus tard, il semble que le seul navigateur semi-récent qui ne le supporte pas soit IE 9.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X