Obtenir les valeurs d'URL des paramètres de chaîne de requête avec jQuery / Javascript (chaîne de requête)

150

Quelqu'un connaît-il un bon moyen d'écrire une extension jQuery pour gérer les paramètres de chaîne de requête? Je veux essentiellement étendre la ($)fonction magique jQuery afin de pouvoir faire quelque chose comme ceci:

$('?search').val(); 

Ce qui me donnerait la valeur « test » dans l'URL suivante: http://www.example.com/index.php?search=test.

J'ai vu beaucoup de fonctions qui peuvent faire cela dans jQuery et Javascript, mais je veux en fait étendre jQuery pour qu'il fonctionne exactement comme il est montré ci-dessus. Je ne recherche pas de plugin jQuery, je recherche une extension de la méthode jQuery.

TroySteven
la source
4
Interrogé et répondu: stackoverflow.com/questions/901115/…
Nico Westerdale
1
@NicoWesterdale - J'ai parcouru ce lien, mais je n'ai vu aucune réponse qui résout cette question particulière. Il a dit qu'il voulait exactement comme ci-dessus.
mrtsherman
2
Je ne pense pas que vous puissiez faire cela, une chaîne passée est analysée par Sizzler, puis résolue en un tableau d'objets DOM. Vous pouvez étendre le matcher pour fournir des filtres personnalisés, mais vous ne pouvez pas avoir d'objet jquery basé sur une chaîne.
Andrew
6
N'est-ce pas $assez surchargé?
Quentin
1
@mrtsherman Regardez la fonction getParameterByName () dans le lien que j'ai fourni. Non, vous ne pouvez pas le faire directement dans une invite $, mais ce n'est pas à cela que servent les sélecteurs jQuery. Il sélectionne simplement une partie d'une chaîne d'URL, n'essaye pas d'accéder à une partie du DOM, ce que fait $ (). C'est une chose totalement différente. Si vous voulez vraiment utiliser jQuery, vous pouvez écrire un plugin qui utilise cette syntaxe: $ .getParameterByName (param), il y a un exemple plus bas sur cette page que j'ai liée qui fait exactement cela. Un peu inutile cependant.
Nico Westerdale

Réponses:

47

Après des années d'analyse de chaînes horribles, il existe un meilleur moyen: URLSearchParams Voyons comment nous pouvons utiliser cette nouvelle API pour obtenir des valeurs à partir de l'emplacement!

// En supposant "? Post = 1234 & action = edit"

var urlParams = new URLSearchParams(window.location.search);
console.log(urlParams.has('post')); // true
console.log(urlParams.get('action')); // "edit"
console.log(urlParams.getAll('action')); // ["edit"]
console.log(urlParams.toString()); // "?post=1234&action=edit"
console.log(urlParams.append('active', '1')); // "?

post=1234&action=edit&active=1"

MISE À JOUR: IE n'est pas pris en charge

utilisez cette fonction à partir d' une réponse ci-dessous au lieu de URLSearchParams

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('action')); //edit
Saurin
la source
1
URLSearchParams est-il pris en charge par tous les navigateurs?
divin
Oups! ohh man, IE n'est pas pris en charge !! Je viens de tester dessus. Alors que Chrome, FF, Safari n'a aucun problème.
Saurin
1
@divine - Il y a un polyfill pour URLSearchParams ici: github.com/WebReflection/url-search-params
Roberto
Si vous ajoutez un polyfill pour les navigateurs non pris en charge, cette solution URLSearchParams fonctionne bien. github.com/ungap/url-search-params
Louisvdw
104

Pourquoi étendre jQuery? Quel serait l'avantage d'étendre jQuery par rapport à une simple fonction globale?

function qs(key) {
    key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&"); // escape RegEx meta chars
    var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
    return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}

http://jsfiddle.net/gilly3/sgxcL/

Une autre approche consisterait à analyser la chaîne de requête entière et à stocker les valeurs dans un objet pour une utilisation ultérieure. Cette approche ne nécessite pas d'expression régulière et étend l' window.locationobjet (mais pourrait tout aussi bien utiliser une variable globale):

location.queryString = {};
location.search.substr(1).split("&").forEach(function (pair) {
    if (pair === "") return;
    var parts = pair.split("=");
    location.queryString[parts[0]] = parts[1] &&
        decodeURIComponent(parts[1].replace(/\+/g, " "));
});

http://jsfiddle.net/gilly3/YnCeu/

Cette version utilise également Array.forEach(), qui n'est pas disponible nativement dans IE7 et IE8. Il peut être ajouté en utilisant l'implémentation chez MDN , ou vous pouvez utiliser jQuery à la $.each()place.

gilly3
la source
2
Ce n'est pas courant, mais il est valide d'utiliser des points-virgules au lieu d'esperluettes dans les paramètres de requête.
Muhd
@Muhd - Il est "valide" d'utiliser n'importe quel délimiteur que vous aimez dans une chaîne de requête tant que votre code le comprend. Mais, lorsqu'un formulaire est soumis, les champs du formulaire sont soumis par name=valuepaires, séparés par &. Si votre code utilise un format de chaîne de requête personnalisé, vous devrez évidemment écrire un analyseur de chaîne de requête personnalisé partout où la chaîne de requête est consommée, que ce soit sur le serveur ou le client.
gilly3
2
@nick - Intéressant. Mais leur suggestion pour les serveurs HTTP de traiter les points-virgules comme des esperluettes ne sert qu'à rendre HTML plus joli lors de l'utilisation d'un lien pour imiter une soumission de formulaire. Ce n'est qu'une suggestion et n'est pas standard. Une GETsoumission de formulaire standard est codée comme application/x-www-form-urlencoded, avec des valeurs séparées par &. Mon code gère cette norme. Les structures d'URL personnalisées telles que celle que vous avez liée nécessiteront un analyseur personnalisé côté serveur et côté client. Quoi qu'il en soit, ajouter une telle capacité à mon code ci-dessus serait trivial.
gilly3
1
@gilly en effet - si vous voulez du code portable, vous devez prendre en charge les deux
nick
1
Ajoutez "i" à RegExp () pour que la clé ne soit pas sensible à la casse: new RegExp ("[? &]" + Key + "= ([^ &] +) (& | $)", "i"));
Yovav
94

Le plugin JQuery jQuery-URL-Parser fait le même travail, par exemple pour récupérer la valeur du paramètre de chaîne de requête de recherche , vous pouvez utiliser

$.url().param('search');

Cette bibliothèque n'est pas activement maintenue. Comme le suggère l'auteur du même plug - in, vous pouvez utiliser URI.js .

Ou vous pouvez utiliser js-url à la place. C'est assez similaire à celui ci-dessous.

Ainsi, vous pouvez accéder au paramètre de requête comme $.url('?search')

RameshVel
la source
2
Agréable. Et le code est dans le domaine public, vous n'avez donc même pas à inclure les commentaires.
Muhd
4
Bonne solution mais ne fonctionnera pas si vous testez via file: //
kampsj
1
Qu'est-ce qui a à voir avec, @kampsj
RameshVel
3
Salut @kampsj, tester avec le file://protocole empêchera beaucoup plus de choses de fonctionner. Vous pouvez créer un serveur HTML statique très rapide et simple avec node.js. stackoverflow.com/questions/16333790/…
Jess
2
Ce plugin n'est plus maintenu et l'auteur lui-même suggère d'utiliser d'autres plugins à la place.
JanErikGunnar
77

J'ai trouvé ce bijou de nos amis sur SitePoint. https://www.sitepoint.com/url-parameters-jquery/ .

Utilisation de PURE jQuery. Je viens de l'utiliser et cela a fonctionné. Je l'ai un peu modifié par exemple pour le saké.

//URL is http://www.example.com/mypage?ref=registration&[email protected]

$.urlParam = function (name) {
    var results = new RegExp('[\?&]' + name + '=([^&#]*)')
                      .exec(window.location.search);

    return (results !== null) ? results[1] || 0 : false;
}

console.log($.urlParam('ref')); //registration
console.log($.urlParam('email')); //[email protected]

Utilisez comme vous voudrez.

ClosDesign
la source
Génial. Merci! Je ne pense pas que vous ayez besoin de la dernière balise d'accolade de fermeture.
bhtabor
Ahh oui, vous avez raison. Modifié le message. Cela a été laissé par une déclaration if dans mon code. Merci.
ClosDesign
1
Vous devriez utiliser window.location.search au lieu de .href - sinon, c'est bien.
BrainSlugs83
4
Au lieu de results[1] || 0, vous devez faire if (results) {return results [1]} return 0; Les paramètres de requête bcoz peuvent ne pas être présents du tout. Et la modification gérera tous les cas génériques.
myDoggyWritesCode
1
Que faites-vous si vous avez quelque chose comme ça https://example.com/?c=Order+ID? Ce signe plus reste toujours sur cette fonction.
Volomike
47

Ce n'est pas mon exemple de code, mais je l'ai utilisé dans le passé.

//First Add this to extend jQuery

    $.extend({
      getUrlVars: function(){
        var vars = [], hash;
        var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
        for(var i = 0; i < hashes.length; i++)
        {
          hash = hashes[i].split('=');
          vars.push(hash[0]);
          vars[hash[0]] = hash[1];
        }
        return vars;
      },
      getUrlVar: function(name){
        return $.getUrlVars()[name];
      }
    });

    //Second call with this:
    // Get object of URL parameters
    var allVars = $.getUrlVars();

    // Getting URL var by its name
    var byName = $.getUrlVar('name');
Rob Nield
la source
2
Vous ne devriez pas diviser sur '=', il est techniquement acceptable d'avoir un deuxième signe égal dans la valeur de n'importe quelle paire clé / valeur. - Seul le premier signe égal que vous rencontrez (par paire clé / valeur) doit être traité comme un délimiteur. (De plus, le signe égal n'est pas strictement requis; il est possible d'avoir une clé sans valeur.)
BrainSlugs83
Solution propre. A parfaitement fonctionné dans mon cas.
JF Gagnon
$ .extend ({getUrlVars: function () {var vars = [], hash; var hashes = window.location.href.slice (window.location.href.indexOf ('?') + 1) .split ('& '); for (var i = 0; i <hashes.length; i ++) {hash = hashes [i] .split (' = '); var k = hash.shift (); vars.push (k); vars [k] = hash.join ("");} return vars;}, getUrlVar: function (name) {return $ .getUrlVars () [name];}});
Mupinc
15

J'ai écrit une petite fonction où vous n'avez qu'à analyser le nom du paramètre de requête. Donc, si vous avez:? Project = 12 & Mode = 200 & date = 2013-05-27 et que vous voulez le paramètre 'Mode', il vous suffit d'analyser le nom 'Mode' dans la fonction:

function getParameterByName( name ){
    var regexS = "[\\?&]"+name+"=([^&#]*)", 
  regex = new RegExp( regexS ),
  results = regex.exec( window.location.search );
  if( results == null ){
    return "";
  } else{
    return decodeURIComponent(results[1].replace(/\+/g, " "));
  }
}

// example caller:
var result =  getParameterByName('Mode');
Plippie
la source
Si votre nom n'a pas de courrier indésirable, vous pouvez supprimer la première expression régulière et il est plus logique de commencer à partir de location.search
mplungjan
7

En s'appuyant sur la réponse de @Rob Neild ci-dessus, voici une pure adaptation JS qui renvoie un objet simple de paramètres de chaîne de requête décodés (pas de% 20, etc.).

function parseQueryString () {
  var parsedParameters = {},
    uriParameters = location.search.substr(1).split('&');

  for (var i = 0; i < uriParameters.length; i++) {
    var parameter = uriParameters[i].split('=');
    parsedParameters[parameter[0]] = decodeURIComponent(parameter[1]);
  }

  return parsedParameters;
}

la source
Je n'ai vu aucune erreur en utilisant ce code. Quel navigateur utilisez-vous? Je l'ai testé avec Firefox, Chrome et Safari actuels.
Ouais désolé je l'ai mal lu. Je pensais l'avoir vu appeler une méthode sur quelque chose qui retournait indéfini. Donc, en réalité, il ne fonctionne qu'une seule fois alors que ce n'est pas nécessaire. Lorsque la recherche est "". Et vous obtenez {"": "undefined"}
Jerinaw
Ouais. Cela pourrait probablement nécessiter un certain raffinement.
1

Écrit en Javascript vanille

     //Get URL
     var loc = window.location.href;
     console.log(loc);
     var index = loc.indexOf("?");
     console.log(loc.substr(index+1));
     var splitted = loc.substr(index+1).split('&');
     console.log(splitted);
     var paramObj = [];
     for(var i=0;i<splitted.length;i++){
         var params = splitted[i].split('=');
         var key = params[0];
         var value = params[1];
         var obj = {
             [key] : value
         };
         paramObj.push(obj);
         }
    console.log(paramObj);
    //Loop through paramObj to get all the params in query string.
manish Prasad
la source
1
function parseQueryString(queryString) {
    if (!queryString) {
        return false;
    }

    let queries = queryString.split("&"), params = {}, temp;

    for (let i = 0, l = queries.length; i < l; i++) {
        temp = queries[i].split('=');
        if (temp[1] !== '') {
            params[temp[0]] = temp[1];
        }
    }
    return params;
}

J'utilise ça.

donvercety
la source