434 votes

Comment convertir les paramètres d'une URL en un objet JavaScript ?

J'ai une chaîne de caractères comme celle-ci :

abc=foo&def=%5Basf%5D&xyz=5

Comment puis-je le convertir en un objet JavaScript comme celui-ci ?

{
  abc: 'foo',
  def: '[asf]',
  xyz: 5
}

0 votes

1 votes

Ce n'est pas le cas : developer.mozilla.org/fr/US/docs/Web/API/URLSearchParams/ developer.mozilla.org/fr/US/docs/Web/API/URL/ (mais il faudra attendre encore un peu pour que tous les navigateurs le captent).

461voto

amadeus Points 2299

En l'an 2021... Veuillez considérer ceci comme obsolète.

Editar

Cette édition améliore et explique la réponse en se basant sur les commentaires.

var search = location.search.substring(1);
JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}')

Exemple

Analyser abc=foo&def=%5Basf%5D&xyz=5 en cinq étapes :

  • decodeURI : abc=foo&def=[asf]&xyz=5
  • Échapper aux guillemets : même chose, car il n'y a pas de guillemets.
  • Remplacer & : abc=foo","def=[asf]","xyz=5
  • Remplacer = : abc":"foo","def":"[asf]","xyz":"5
  • Entourez-vous de boucles et de citations : {"abc":"foo","def":"[asf]","xyz":"5"}

qui est un JSON légal.

Un site solution améliorée permet d'utiliser plus de caractères dans la chaîne de recherche. Il utilise une fonction reviver pour le décodage des URI :

var search = location.search.substring(1);
JSON.parse('{"' + search.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) { return key===""?value:decodeURIComponent(value) })

Exemple

search = "abc=foo&def=%5Basf%5D&xyz=5&foo=b%3Dar";

donne

Object {abc: "foo", def: "[asf]", xyz: "5", foo: "b=ar"}

Réponse originale

Une seule phrase :

JSON.parse('{"' + decodeURI("abc=foo&def=%5Basf%5D&xyz=5".replace(/&/g, "\",\"").replace(/=/g,"\":\"")) + '"}')

4 votes

Pour que cela fonctionne en CoffeeScript, échappez le '=' dans l'expression rationnelle. .replace(/\=/g,"\":\"")

0 votes

Merci pour la réponse. Peut-être qu'expliquer ce que fait chaque partie aiderait certaines personnes à mieux comprendre plutôt que de simplement copier+coller+espérer que ça marche. - Laissons les "one liners" aux minifieurs :)

0 votes

Cela ne permet pas d'échapper aux guillemets comme il se doit. Ajouter .replace(/"/g,'\\"')

34voto

lwburk Points 29313

Split on & pour obtenir des paires nom/valeur, puis diviser chaque paire sur = . Voici un exemple :

var str = "abc=foo&def=%5Basf%5D&xy%5Bz=5"
var obj = str.split("&").reduce(function(prev, curr, i, arr) {
    var p = curr.split("=");
    prev[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
    return prev;
}, {});

Une autre approche, l'utilisation d'expressions régulières :

var obj = {}; 
str.replace(/([^=&]+)=([^&]*)/g, function(m, key, value) {
    obj[decodeURIComponent(key)] = decodeURIComponent(value);
}); 

Ceci est adapté du livre de John Resig "Cherchez et ne remplacez pas" .

0 votes

Tx ! vous devriez aussi ajouter decodeURIComponen(p[0]) à gauche :)

0 votes

Le premier exemple ne fonctionne pas avec une chaîne de requête vide.

18voto

Justin Niessner Points 144953

Il s'agit d'une version simple, mais il est évident que vous devrez ajouter des contrôles d'erreurs :

var obj = {};
var pairs = queryString.split('&');
for(i in pairs){
    var split = pairs[i].split('=');
    obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]);
}

1 votes

N'avez-vous pas oublié de désencoder la chaîne pour convertir les %5B et %5D en caractères ?

0 votes

@Alex - Avez-vous utilisé le code mis à jour ou l'original ? L'original avait un problème et une faute de frappe.

1 votes

Il ne peut pas gérer correctement les paramètres lorsque leurs valeurs contiennent '='. Il réduit les valeurs au premier '='.

10voto

Daff Points 22358

J'ai trouvé $.String.deparam la solution préconstruite la plus complète (peut faire des objets imbriqués, etc.). Consultez le site documentation .

0 votes

Je signale simplement que si votre entrée doit toujours être une chaîne de requête sérialisée, il n'est pas nécessaire de s'inquiéter de l'imbrication et une solution plus légère est probablement préférable.

0 votes

Bien sûr... mais cela a déjà été fait et testé (Justin, par exemple, a oublié de décoder l'URI dans la réponse initiale - ce sont de petits problèmes qui peuvent rendre les choses beaucoup plus complexes qu'elles ne le semblent au départ).

3voto

mattacular Points 1446

À ma connaissance, il n'existe pas de solution native. Dojo a une méthode de désérialisation intégrée si vous utilisez ce framework par hasard.

Sinon, vous pouvez le mettre en œuvre vous-même assez simplement :

function unserialize(str) {
  str = decodeURIComponent(str);
  var chunks = str.split('&'),
      obj = {};
  for(var c=0; c < chunks.length; c++) {
    var split = chunks[c].split('=', 2);
    obj[split[0]] = split[1];
  }
  return obj;
}

edit : ajouté decodeURIComponent()

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