web-dev-qa-db-fra.com

Convertir une chaîne d'objet en JSON

Comment puis-je convertir une chaîne qui décrit un objet en une chaîne JSON en utilisant JavaScript (ou jQuery)?

par exemple: Convertissez cette (PASune chaîne JSON valide):

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"

dans ceci:

str = '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

J'aimerais éviter d'utiliser eval() si possible.

155
snorpey

Si la chaîne provient d'une source fiable , vous pouvez utiliser eval puis JSON.stringify le résultat. Comme ça:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));

Notez que lorsque vous eval un littéral d'objet, il doit être entouré de parenthèses, sinon les accolades sont analysées comme un bloc au lieu d'un objet.

Je suis également d'accord avec les commentaires sous la question qu'il serait beaucoup mieux de commencer par encoder l'objet en JSON valide et d'éviter de devoir analyser, encoder, puis vraisemblablement l'analyser again. HTML prend en charge les attributs entre guillemets (veillez simplement à coder HTML les guillemets simples dans les chaînes).

172
Matthew Crumley

Votre chaîne n'est pas un code JSON valide. Par conséquent, JSON.parse (ou $.parseJSON de jQuery) ne fonctionnera pas.

Une solution serait d'utiliser eval pour "analyser" le JSON "non valide", puis stringify pour le "convertir" en JSON valide.

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
str = JSON.stringify(eval('('+str+')'));

Je suggère au lieu d'essayer de "réparer" votre JSON invalide, vous commencez par un JSON valide. Comment str est généré, il devrait être corrigé ici, avant sa génération, pas après.

EDIT: Vous avez dit (dans les commentaires) que cette chaîne est stockée dans un attribut de données:

<div data-object="{hello:'world'}"></div>

Je suggère que vous le répariez ici, donc ça peut simplement être JSON.parsed. Premièrement, les clés et les valeurs doivent être entre guillemets doubles. Cela devrait ressembler à (les attributs entre guillemets HTML sont valides):

<div data-object='{"hello":"world"}'></div>

Maintenant, vous pouvez simplement utiliser JSON.parse (ou le $.parseJSON de jQuery).

var str = '{"hello":"world"}';
var obj = JSON.parse(str);
107
Rocket Hazmat

jQuery.parseJSON

str = jQuery.parseJSON(str)

Modifier. Ceci est fourni si vous avez une chaîne JSON valide

49
Farmor

Utilisez un code simple dans le lien ci-dessous:

http://msdn.Microsoft.com/es-es/library/ie/cc836466%28v=vs.94%29.aspx

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);

et inverser

var str = JSON.stringify(arr);
39
Ronald

J'espère que cette petite fonction convertit une chaîne JSON non valide en une chaîne valide.

function JSONize(str) {
  return str
    // wrap keys without quote with valid double quote
    .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":'})    
    // replacing single quote wrapped ones to double quote 
    .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"'})         
}

Résultat

var invalidJSON = "{ hello: 'world',foo:1,  bar  : '2', foo1: 1, _bar : 2, $2: 3, 'xxx': 5, \"fuz\": 4, places: ['Africa', 'America', 'Asia', 'Australia'] }"
JSON.parse(invalidJSON) 
//Result: Uncaught SyntaxError: Unexpected token h VM1058:2
JSON.parse(JSONize(invalidJSON)) 
//Result: Object {hello: "world", foo: 1, bar: "2", foo1: 1, _bar: 2…}
22
allenhwkim

À utiliser avec prudence (à cause de eval()):

function strToJson(str) {
  eval("var x = " + str + ";");
  return JSON.stringify(x);
}

appeler comme:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
alert( strToJson(str) );
9
Tomalak

Je mets ma réponse pour quelqu'un qui s'intéresse à ce vieux fil.

J'ai créé l'analyseur HTML5 data- * for jQuery plugin et demo qui convertit une chaîne JSON mal formée en un objet JavaScript sans utiliser eval().

Il peut passer les attributs HTML5 data- * ci-dessous:

<div data-object='{"hello":"world"}'></div>
<div data-object="{hello:'world'}"></div>
<div data-object="hello:world"></div>

dans l'objet:

{
    hello: "world"
}
4
tokkonopapa

Avertissement: n'essayez pas cela à la maison ou pour tout ce qui nécessite que d'autres développeurs vous prennent au sérieux:

JSON.stringify(eval('(' + str + ')'));

Là je l'ai fait.
Essayez de ne pas le faire, eval est MAUVAIS pour vous. Comme indiqué ci-dessus, utilisez la cale JSON de Crockford pour les anciens navigateurs (IE7 et moins).

Cette méthode nécessite que votre chaîne soit valide javascript , qui sera converti en un objet javascript qui peut ensuite être sérialisé en JSON.

edit: corrigé comme suggéré par Rocket.

4
gonchuki

Douglas Crockford a un convertisseur, mais je ne suis pas sûr que cela aidera avec un mauvais JSON à bon.

https://github.com/douglascrockford/JSON-js

2
Seth

Vous devez utiliser "eval" puis JSON.stringify puis JSON.parse au résultat.

 var errorString= "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
 var jsonValidString = JSON.stringify(eval("(" + errorString+ ")"));
 var JSONObj=JSON.parse(jsonValidString);

 enter image description here

2
Negi Rox

Votre meilleur et plus sûr pari serait JSON5 - JSON pour les humains . Il est créé spécifiquement pour ce cas d'utilisation.

const result = JSON5.parse("{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }");

console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/0.5.1/json5.min.js"></script>

1
dereli

Vous devez écrire des crochets, car sans eux eval considérera le code entre accolades comme un bloc de commandes ..__

var i = eval("({ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] })");
1
kuboslav

Il existe un moyen beaucoup plus simple d'accomplir cet exploit: il suffit de détourner l'attribut onclick d'un élément factice pour forcer le retour de votre chaîne en tant qu'objet JavaScript:

var jsonify = (function(div){
  return function(json){
    div.setAttribute('onclick', 'this.__json__ = ' + json);
    div.click();
    return div.__json__;
  }
})(document.createElement('div'));

// Let's say you had a string like '{ one: 1 }' (malformed, a key without quotes)
// jsonify('{ one: 1 }') will output a good ol' JS object ;)

Voici une démo:http://codepen.io/csuwldcat/pen/dfzsu (ouvrez votre console)

1
csuwldcat

Peut-être que vous devez essayer ceci:

str = jQuery.parseJSON(str)
0
howdyhyber

Juste pour les bizarreries, vous pouvez convertir votre chaîne via babel-standalone

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";

function toJSON() {
  return {
    visitor: {
      Identifier(path) {
        path.node.name = '"' + path.node.name + '"'
      },
      StringLiteral(path) {
        delete path.node.extra
      }
    }
  }
}
Babel.registerPlugin('toJSON', toJSON);
var parsed = Babel.transform('(' + str + ')', {
  plugins: ['toJSON']
});
var json = parsed.code.slice(1, -2)
console.log(JSON.parse(json))
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>

0
Moritz Roessler

Pour votre exemple simple ci-dessus, vous pouvez le faire en utilisant 2 simples regex simples:

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
str.replace(/(\w+):/g, '"$1":').replace(/'/g, '"');
 => '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

Big caveat : Cette approche naïve suppose que l'objet ne comporte aucune chaîne contenant un caractère ' ou :. Par exemple, je ne peux pas trouver un bon moyen de convertir la chaîne d'objet suivante en JSON sans utiliser eval:

"{ hello: 'world', places: [\"America: The Progressive's Nightmare\"] }"
0
Topher Hunt

var str = "{bonjour: 'monde', lieux: ['Afrique', 'Amérique', 'Asie', 'Australie']}" var fStr = str . remplacer (/ ([Az] *) (:)/g, '"$ 1":') . remplacer (/ '/ g, "\" ")

console.log (JSON.parse (fStr))enter image description here

Désolé je suis sur mon téléphone, voici une photo. 

0
Francis Leigh
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));
0
praveenkumar

Une solution avec un regex et n'utilisant pas eval:

str.replace(/([\s\S]*?)(')(.+?)(')([\s\S]*?)/g, "$1\"$3\"$5")

Je pense que cela devrait fonctionner pour plusieurs lignes et toutes les occurrences possibles (indicateur/g) de "chaîne" entre guillemets remplacés par "chaîne" entre guillemets doubles.

0
Chaitanya P

Utiliser une nouvelle fonction () est préférable à eval, mais ne devrait toujours être utilisé qu'avec une entrée sécurisée.

const parseJSON = obj => Function('"use strict";return (' + obj + ')')();

console.log(parseJSON("{a:(4-1), b:function(){}, c:new Date()}"))
// outputs: Object { a: 3, b: b(), c: Date 2019-06-05T09:55:11.777Z }

Sources: MDN , 2ality

0
SamGoody