Chaîne de requête JavaScript [fermée]

106

Existe-t-il une bibliothèque JavaScript qui crée un dictionnaire à partir de la chaîne de requête, ASP.NETstyle?

Quelque chose qui peut être utilisé comme:

var query = window.location.querystring["query"]?

La "chaîne de requête" est-elle appelée autre chose en dehors du .NETroyaume? Pourquoi n'est-il pas location.searchdivisé en une collection de clés / valeurs ?

EDIT : J'ai écrit ma propre fonction, mais est-ce qu'une bibliothèque JavaScript majeure le fait?

coeur
la source
3
trouvé ceci: medialize.github.com/URI.js
deerchao
1
@davidtaubmann que l'on est plus âgé, ce serait l'inverse. C'est drôle qu'ils posent essentiellement la même chose, mais en raison du format de la question, la gloire a été transformée en communauté et d'autres fermées comme hors sujet.
Andre Figueiredo

Réponses:

11

Peut-être http://plugins.jquery.com/query-object/ ?

C'est la fourchette https://github.com/sousk/jquery.parsequery#readme .

Ombre2531
la source
37
Cela devrait être natif de jquery
gcb
@EvanMulawski Merci. Le plug-in a tout simplement disparu, semble-t-il. J'ai ajouté un lien différent, ce qui pourrait aider.
Shadow2531
La méthode fournie par CMS est plus simple et plus propre. Esp. si vous n'utilisez pas déjà jquery.
jcoffland
1
Vous pouvez vous référer à cette bibliothèque pour le faire - github.com/Mikhus/jsurl
Mikhus
1
Voici le lien approprié: plugins.jquery.com/query-object
thexfactor
230

Vous pouvez extraire les paires clé / valeur de la propriété location.search , cette propriété a la partie de l'URL qui suit le? symbole, y compris le? symbole.

function getQueryString() {
  var result = {}, queryString = location.search.slice(1),
      re = /([^&=]+)=([^&]*)/g, m;

  while (m = re.exec(queryString)) {
    result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }

  return result;
}

// ...
var myParam = getQueryString()["myParam"];
CMS
la source
11
Ce n'est pas une victoire. Que faire si la valeur d'une clé contient le caractère «=»? Par exemple, dork.com/?equation=10=2. Vous pourriez dire qu'il DEVRAIT être encodé en URL, mais ce n'est certainement pas nécessaire. J'ai commis l'erreur d'écrire moi-même une fonction naïve comme celle-ci. Cette fonction compte plusieurs cas de bord.
JamesBrownIsDead
6
@James, j'ai oublié de mentionner qu'il y a quelques mois, j'ai modifié la fonction, maintenant elle peut gérer correctement votre exemple dork.com/?equation=10=2...
CMS
2
@CMS cela ne gère pas la possibilité d'un tableau dans une chaîne de requête qui est représentée comme telle, ?val=foo&val=bar&val=baz comment pouvez-vous gérer cela?
Russ Bradberry
2
@RussBradberry Vous ne pouvez pas vraiment avoir val=foo&val=bar&val=baz; ça devrait êtreval[]=foo&val[]=bar&val[]=baz
Brian Driscoll
1
Cela me semblait incomplet lorsque mes valeurs avaient des espaces et que mes variables se terminaient par des %20's, alors j'ai remplacé result[keyValuePair[0]] = keyValuePair[1] || '';parresult[keyValuePair[0]] = decodeURIComponent((keyValuePair[1]+'').replace(/\+/g, '%20')) || '';
user24601
22

tl; dr solution sur une seule ligne (ish) de code en utilisant du javascript vanille

var queryDict = {}
location.search.substr(1).split("&").forEach(function(item) {
    queryDict[item.split("=")[0]] = item.split("=")[1]
})

Pour la chaîne de requête, ?a=1&b=2&c=3&d&eil renvoie:

> queryDict
a: "1"
b: "2"
c: "3"
d: undefined
e: undefined

clés à valeurs multiples et caractères codés ?

Voir la réponse originale sur Comment puis-je obtenir des valeurs de chaîne de requête en JavaScript?

"?a=1&b=2&c=3&d&e&a=5&a=t%20e%20x%20t&e=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dståle%26car%3Dsaab"
> queryDict
a: ["1", "5", "t e x t"]
b: ["2"]
c: ["3"]
d: [undefined]
e: [undefined, "http://w3schools.com/my test.asp?name=ståle&car=saab"]
Qwerty
la source
8
ce n'est pas une seule ligne - ce sont plusieurs lignes mal formatées!
JonnyRaa
1
Merde, je ne sais pas quoi dire ... Tu m'as eu. Voici une solution multiligne: `var queryDict = {}; location.search.substr (1) .split ("&"). forEach (fonction (élément) {queryDict [élément.split ("=") [0]] = item.split ("=") [1]; }); `
Qwerty
2
haha je l'adore! Désolée, j'avais l'habitude de travailler avec quelqu'un qui disait «J'ai trouvé une ligne unique qui fait x», puis je vous montre simplement 3 lignes avec les sauts de ligne supprimés!
JonnyRaa
@JonnyLeeds Pas de problème, je sais exactement ce que vous voulez dire, mais alors, pourquoi écrirait-on chacune des commandes enchaînées sur une nouvelle ligne? Ensuite, il y a une fonction donnée en paramètre (les paramètres sont généralement en ligne) qui n'a qu'une seule affectation. Il crie d'être intégré! : D
Qwerty
1
@Qwerty, c'est probablement parce que votre "one-liner" doit être reformaté pour que sa lecture ne nécessite pas de défilement horizontal. Je l'ai ajusté.
P i
8

Après avoir trouvé ce post, en me regardant, j'ai pensé que je devrais ajouter que je ne pense pas que la solution la plus votée soit la meilleure. Il ne gère pas les valeurs de tableau (comme? A = foo & a = bar - dans ce cas, je m'attendrais à ce que un retourne ['foo', 'bar']). Autant que je sache, il ne prend pas non plus en compte les valeurs codées - comme le codage de caractères hexadécimaux où% 20 représente un espace (exemple:? A = Hello% 20World) ou le symbole plus utilisé pour représenter un espace (exemple :? a = Bonjour + Monde).

Node.js offre ce qui ressemble à une solution très complète pour l'analyse des chaînes de requêtes. Il serait facile à retirer et à utiliser dans votre propre projet car il est assez bien isolé et sous licence permissive.

Le code correspondant peut être consulté ici: https://github.com/joyent/node/blob/master/lib/querystring.js

Les tests que Node a peuvent être vus ici: https://github.com/joyent/node/blob/master/test/simple/test-querystring.js Je suggérerais d'essayer certains d'entre eux avec la réponse populaire pour voir comment cela les gère.

Il y a aussi un projet dans lequel j'ai été impliqué pour ajouter spécifiquement cette fonctionnalité. Il s'agit d'un portage du module d'analyse de chaîne de requête de la bibliothèque standard Python. Ma fourche se trouve ici: https://github.com/d0ugal/jquery.qeeree

d0ugal
la source
Il n'y a pas que d'emprunter le code de Node, js, il est fortement imbriqué.
alfwatt
5

Ou vous pouvez utiliser la bibliothèque sugar.js .

De sugarjs.com:

Object.fromQueryString (str , deep = true )

Convertit la chaîne de requête d'une URL en objet. Si deep est faux, la conversion n'acceptera que les paramètres superficiels (c'est-à-dire pas d'objet ou de tableaux avec la syntaxe []) car ils ne sont pas universellement pris en charge.

Object.fromQueryString('foo=bar&broken=wear') >{"foo":"bar","broken":"wear"}
Object.fromQueryString('foo[]=1&foo[]=2') >{"foo":[1,2]}

Exemple:

var queryString = Object.fromQueryString(location.search);
var foo = queryString.foo;
Andersh
la source
3

Si vous avez la chaîne de requête sous la main, utilisez ceci:

 /**
 * @param qry the querystring
 * @param name name of parameter
 * @returns the parameter specified by name
 * @author [email protected]
 */

function getQueryStringParameter(qry,name){
    if(typeof qry !== undefined && qry !== ""){
        var keyValueArray = qry.split("&");
        for ( var i = 0; i < keyValueArray.length; i++) {
            if(keyValueArray[i].indexOf(name)>-1){
                return keyValueArray[i].split("=")[1];
            }
        }
    }
    return "";
}
Eduardo
la source
2
// How about this
function queryString(qs) {
    var queryStr = qs.substr(1).split("&"),obj={};
    for(var i=0; i < queryStr.length;i++)
        obj[queryStr[i].split("=")[0]] = queryStr[i].split("=")[1];
    return obj;
}

// Usage:
var result = queryString(location.search);
Ryan C Knaggs
la source
C'est plus ou moins la même chose que le code "Mise à jour: pas besoin d'utiliser l'expression régulière" dans la réponse la plus votée ci - dessus. Il y a aussi beaucoup de code similaire dans cette question ). Vous decodeURIComponentmanquez au moins les chaînes extraites.
Rup
@Rup, la mise à jour a été faite après cette réponse.
Qwerty
@Qwerty Non, ce n'était pas le cas: la mise à jour était en février 2013 alors que cette réponse était près d'un an plus tard en février 2014. Mais qu'importe, il y a beaucoup de codes similaires qui volent. Mes commentaires sur le decodeURIComponentstand, cependant.
Rup
@Rup Yup, désolé. Et oui.
Qwerty
2

Il est à noter que la bibliothèque mentionnée par John Slegers a une dépendance jQuery, mais voici une version qui est Javascript vanille.

https://github.com/EldonMcGuinness/querystring.js

J'aurais simplement commenté son message, mais je n'ai pas la réputation de le faire. : /

Exemple:

L'exemple ci-dessous traite la chaîne de requête suivante, quoique irrégulière:

?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab 

var qs = "?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab";
//var qs = "?=&=";
//var qs = ""

var results = querystring(qs);

(document.getElementById("results")).innerHTML =JSON.stringify(results, null, 2);
<script 
src="https://rawgit.com/EldonMcGuinness/querystring.js/master/dist/querystring.min.js"></script>
<pre id="results">RESULTS: Waiting...</pre>

Eldon McGuinness
la source
En fait, j'ai supprimé la dépendance jQuery dans le code que j'ai donné dans ma réponse ;-)
John Slegers
2

Le code

This Gist par Eldon McGuinness est de loin l'implémentation la plus complète d'un analyseur de chaîne de requête JavaScript que j'ai vu jusqu'à présent.

Malheureusement, il est écrit comme un plugin jQuery.

Je l'ai réécrit en vanilla JS et j'ai apporté quelques améliorations:

function parseQuery(str) {
  var qso = {};
  var qs = (str || document.location.search);
  // Check for an empty querystring
  if (qs == "") {
    return qso;
  }
  // Normalize the querystring
  qs = qs.replace(/(^\?)/, '').replace(/;/g, '&');
  while (qs.indexOf("&&") != -1) {
    qs = qs.replace(/&&/g, '&');
  }
  qs = qs.replace(/([\&]+$)/, '');
  // Break the querystring into parts
  qs = qs.split("&");
  // Build the querystring object
  for (var i = 0; i < qs.length; i++) {
    var qi = qs[i].split("=");
    qi = qi.map(function(n) {
      return decodeURIComponent(n)
    });
    if (typeof qi[1] === "undefined") {
      qi[1] = null;
    }
    if (typeof qso[qi[0]] !== "undefined") {

      // If a key already exists then make this an object
      if (typeof (qso[qi[0]]) == "string") {
        var temp = qso[qi[0]];
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]] = [];
        qso[qi[0]].push(temp);
        qso[qi[0]].push(qi[1]);

      } else if (typeof (qso[qi[0]]) == "object") {
        if (qi[1] == "") {
          qi[1] = null;
        }
        qso[qi[0]].push(qi[1]);
      }
    } else {
      // If no key exists just set it as a string
      if (qi[1] == "") {
        qi[1] = null;
      }
      qso[qi[0]] = qi[1];
    }
  }
  return qso;
}

Comment l'utiliser

var results = parseQuery("?foo=bar&foo=boo&roo=bar;bee=bop;=ghost;=ghost2;&;checkbox%5B%5D=b1;checkbox%5B%5D=b2;dd=;http=http%3A%2F%2Fw3schools.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab&http=http%3A%2F%2Fw3schools2.com%2Fmy%20test.asp%3Fname%3Dst%C3%A5le%26car%3Dsaab");

Production

{
  "foo": ["bar", "boo" ],
  "roo": "bar",
  "bee": "bop",
  "": ["ghost", "ghost2"],
  "checkbox[]": ["b1", "b2"],
  "dd": null,
  "http": [
    "http://w3schools.com/my test.asp?name=ståle&car=saab",
    "http://w3schools2.com/my test.asp?name=ståle&car=saab"
  ]
}

Voir aussi ce violon .

John Slegers
la source
1

function decode(s) {
    try {
        return decodeURIComponent(s).replace(/\r\n|\r|\n/g, "\r\n");
    } catch (e) {
        return "";
    }
}
function getQueryString(win) {
    var qs = win.location.search;
    var multimap = {};
    if (qs.length > 1) {
        qs = qs.substr(1);
        qs.replace(/([^=&]+)=([^&]*)/g, function(match, hfname, hfvalue) {
            var name = decode(hfname);
            var value = decode(hfvalue);
            if (name.length > 0) {
                if (!multimap.hasOwnProperty(name)) {
                    multimap[name] = [];
                }
                multimap[name].push(value);
            }
        });
    }
    return multimap;
}
var keys = getQueryString(window);
for (var i in keys) {
    if (keys.hasOwnProperty(i)) {
        for (var z = 0; z < keys[i].length; ++z) {
            alert(i + ":" + keys[i][z]);
        }
    }
}
Ombre2531
la source
Vous pouvez également .toLowerCase () le nom si vous voulez que la correspondance hfname soit insensible à la casse.
Shadow2531
Vous pouvez également vérifier si la valeur est vide ou non. Si tel est le cas, vous pouvez ignorer l'ajout de l'entrée afin que le tableau ne contienne que des valeurs non vides.
Shadow2531
1
unescape () ne gère pas les séquences UTF-8, vous pouvez donc utiliser decodeURIComponent (). Cependant, si vous voulez que les caractères + soient décodés en espaces, exécutez .replace (/ \ + / g, "") sur la chaîne avant le décodage.
Shadow2531
1

J'aime le garder simple, lisible et petit.

function searchToObject(search) {
    var pairs = search.substring(1).split("&"),
        obj = {}, pair;

    for (var i in pairs) {
        if (pairs[i] === "") continue;
        pair = pairs[i].split("=");
        obj[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    }
    return obj;
}

searchToObject(location.search);

Exemple:

searchToObject('?query=myvalue')['query']; // spits out: 'myvalue'
André Snede Kock
la source
1

Fonction que j'ai écrite pour une exigence similaire à celle-ci avec une manipulation de chaîne javascript pure

"http://www.google.lk/?Name=John&Age=20&Gender=Male"

function queryize(sampleurl){
    var tokens = url.split('?')[1].split('&');
    var result = {};

    for(var i=0; i<tokens.length; i++){
        result[tokens[i].split('=')[0]] = tokens[i].split('=')[1];
    }

    return result;
}

Usage:

queryize(window.location.href)['Name'] //returns John
queryize(window.location.href)['Age'] //returns 20
queryize(window.location.href)['Gender'] //returns Male
Pranavan Maru
la source
Bien, mais à part la façon dont vous supprimez le début, ?c'est fondamentalement la même chose que les deux réponses ci-dessus?
Rup
Juste une petite amélioration. La manière dont la méthode est utilisée facilite la tâche de l'utilisateur. L'utilisateur a seulement besoin de savoir de quelle valeur de chaîne de requête il a besoin.
Pranavan Maru
1

Si vous utilisez lodash + ES6, voici une solution en une seule ligne: _.object(window.location.search.replace(/(^\?)/, '').split('&').map(keyVal => keyVal.split('=')));

Ben
la source
0

D'accord, puisque tout le monde ignore ma vraie question, hé, je posterai la mienne aussi! Voici ce que j'ai:

location.querystring = (function() {

    // The return is a collection of key/value pairs

    var queryStringDictionary = {};

    // Gets the query string, starts with '?'

    var querystring = unescape(location.search);

    // document.location.search is empty if no query string

    if (!querystring) {
        return {};
    }

    // Remove the '?' via substring(1)

    querystring = querystring.substring(1);

    // '&' seperates key/value pairs

    var pairs = querystring.split("&");

    // Load the key/values of the return collection

    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
        queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
    }

    // Return the key/value pairs concatenated

    queryStringDictionary.toString = function() {

        if (queryStringDictionary.length == 0) {
            return "";
        }

        var toString = "?";

        for (var key in queryStringDictionary) {
            toString += key + "=" + queryStringDictionary[key];
        }

        return toString;
    };

    // Return the key/value dictionary

    return queryStringDictionary;
})();

Et les tests:

alert(window.location.querystring.toString());

for (var key in location.querystring) {
    alert(key + "=" + location.querystring[key]);
}

Rappelez-vous que vous avez pensé, JavaScript n'est pas ma langue maternelle.

Quoi qu'il en soit, je recherche une bibliothèque JavaScript (par exemple jQuery, Prototype) qui en a déjà une écrite. :)

coeur
la source
1
Je ne suis pas convaincu que vous ayez vraiment besoin d'une bibliothèque pour faire ce qui équivaut à trois lignes de code ci-dessus! Pourtant, au moins, vous espérez qu'une bibliothèque se souviendra de decodeURIComponent () à la fois la clé et la valeur, ce que tous les extraits de code publiés jusqu'à présent n'ont pas réussi à faire.
bobince
Vous n'avez pas besoin d'une bibliothèque. Je voulais comparer mon implémentation à une dans une bibliothèque afin de voir s'il me manquait des cas extrêmes. :)
core
javascript n'est pas votre langue maternelle qu'est-ce que cela signifie, vous devriez l'apprendre même si vous avez besoin d'une bibliothèque à utiliser
Marwan
0

En m'appuyant sur la réponse de @CMS, j'ai ce qui suit (dans CoffeeScript qui peut facilement être converti en JavaScript):

String::to_query = ->
  [result, re, d] = [{}, /([^&=]+)=([^&]*)/g, decodeURIComponent]
  while match = re.exec(if @.match /^\?/ then @.substring(1) else @)
    result[d(match[1])] = d match[2] 
  result

Vous pouvez facilement saisir ce dont vous avez besoin avec:

location.search.to_query()['my_param']

La victoire ici est une interface orientée objet (au lieu de fonctionnelle) et cela peut être fait sur n'importe quelle chaîne (pas seulement location.search).

Si vous utilisez déjà une bibliothèque JavaScript, cette fonction existe déjà. Par exemple, voici la version de Prototype

Eric Anderson
la source