Sichere Umwandlung einer JSON-Zeichenfolge in ein Objekt


1336

Wie kann ich angesichts einer Zeichenfolge von JSON-Daten diese Zeichenfolge sicher in ein JavaScript-Objekt umwandeln?

Natürlich kann ich das unsicher machen mit so etwas wie:

var obj = eval("(" + json + ')');

Aber das macht mich anfällig für die JSON-Zeichenfolge, die anderen Code enthält, dessen einfache Auswertung sehr gefährlich erscheint.


77
In den meisten Sprachen birgt eval ein zusätzliches Risiko. Eval lässt eine offene Tür, die von Hackern ausgenutzt werden kann. Denken Sie jedoch daran, dass das gesamte Javascript auf dem Client ausgeführt wird. Erwarten Sie, dass es von Hackern geändert wird. Sie können alles BEWERTEN, was sie wollen, indem sie einfach die Konsole verwenden. Sie müssen Ihren Schutz auf der Serverseite aufbauen.
Beachhouse

19
Ok, jetzt ist es 2014 und Sie sollten es niemals verwenden, evalum eine JSON-Zeichenfolge zu analysieren, da Sie Ihren Code einer "Code-Injection" aussetzen würden. Verwenden Sie JSON.parse(yourString)stattdessen.
Daniel

Sind die JSON-Daten ein Literal?
Shanechiu

@shanechiu: Wenn Sie einen skalaren Datentyp meinen, ist dies der Fall. Ist nur eine Zeichenfolge mit einer Schlüsselwertsyntax.
0zkr PM

Antworten:


1962

JSON.parse(jsonString) ist ein reiner JavaScript-Ansatz, solange Sie einen einigermaßen modernen Browser garantieren können.


74
Ich bin mir ziemlich sicher, dass es für Node.js sicher ist
Stephen

76
@vsync Sie erkennen, dass dies die EINZIGE reine Javascript-Antwort ist ... Wenn Sie die Beschreibung für das Javascript-Tag lesen , wird dies angezeigt ... " Sofern kein Tag für ein Framework / eine Bibliothek enthalten ist, ist eine reine JavaScript-Antwort erwartet. ".. Ich gebe dies eine +1 für die einzige Javascript-Antwort ...
iConnor


12
Wenn Sie NodeJS ausführen, kann ich jQuery auf keinen Fall laden, um einen jsonString in ein JSON-Objekt zu analysieren. Also stimme Jonathans Antwort zu
Antony

6
Laut diesem Link wird es von IE8 + unterstützt, obwohl es heißt:Requires document to be in IE8+ standards mode to work in IE8.
JoshuaDavid

878

Die jQuery-Methode ist jetzt veraltet. Verwenden Sie stattdessen diese Methode:

let jsonObject = JSON.parse(jsonString);

Ursprüngliche Antwort mit veralteter jQuery-Funktionalität :

Wenn Sie jQuery verwenden, verwenden Sie einfach:

jQuery.parseJSON( jsonString );

Es ist genau das, wonach Sie suchen (siehe die jQuery- Dokumentation ).


7
Gibt es einen Grund, dies über JSON.parse () zu verwenden?
Jon

8
jQuery.parseJSONStandardmäßig wird verwendet, JSON.parsewenn es vorhanden ist. Der einzige Grund, dies gegenüber dem realen zu verwenden, besteht darin, dass Sie einen Fallback für <IE7 benötigen. Es wurde vor langer
Karl-Johan Sjögren

9
Update 2016: Ab jQuery 3.0 ist $ .parseJSON veraltet und Sie sollten stattdessen die native JSON.parse-Methode verwenden.
JKDEV

159

Diese Antwort ist für IE <7, für moderne Browser überprüfen Sie Jonathans Antwort oben.

Diese Antwort ist veraltet und Jonathans Antwort oben ( JSON.parse(jsonString)) ist jetzt die beste Antwort .

JSON.org bietet JSON-Parser für viele Sprachen, darunter vier verschiedene für JavaScript. Ich glaube, die meisten Leute würden darüber nachdenken json2.js als ihre Implementierung betrachten.


24
Ich wünschte, die Leute würden aufhören, diese Antwort abzustimmen. Es war genau, als es im Jahr 2008 veröffentlicht wurde. Stimmen Sie einfach das neue ab.
John

22
Wenn die Antwort jetzt veraltet ist, sollten Sie sie aktualisieren.
Sotirios Delimanolis

2
Für IE <8 müssen Sie dies verwenden.
Mahmoodvcs

74

Verwenden Sie das einfache Codebeispiel in " JSON.parse () ":

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

und umgekehrt:

var str = JSON.stringify(arr);

23

Ich bin mir nicht sicher, wie ich es anders machen soll, aber so geht's in Prototype (JSON-Tutorial) .

new Ajax.Request('/some_url', {
  method:'get',
  requestHeaders: {Accept: 'application/json'},
  onSuccess: function(transport){
    var json = transport.responseText.evalJSON(true);
  }
});

Wenn Sie evalJSON()als Argument mit true aufrufen, wird die eingehende Zeichenfolge bereinigt.


22

Dies scheint das Problem zu sein:

Eine Eingabe, die über das Ajax-Websocket usw. empfangen wird und im String-Format vorliegt. Sie müssen jedoch wissen, ob dies der Fall ist JSON.parsable. Das Problem ist, wenn Sie es immer durchlaufen JSON.parse, kann das Programm "erfolgreich" fortgesetzt werden, aber es wird immer noch ein Fehler in der Konsole mit dem gefürchteten angezeigt "Error: unexpected token 'x'".

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});

NEIN. Das Problem ist, dass Sie ein JSON-Objekt erwarten und (function(){ postCookiesToHostileServer(); }());im Kontext von Node möglicherweise noch schlimmeres Zeug haben.
Yaur

Nun, JSON.parse bereinigt die Eingabe von Funktionen (was in diesem Fall nicht als IIF -> Objekt helfen würde). Es scheint, dass der beste Weg, um dieses Thema zu behandeln, Try / Catch ist. (Siehe bearbeiten)
Cody


15
$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Dem Rückruf werden die zurückgegebenen Daten übergeben, bei denen es sich um ein JavaScript-Objekt oder -Array handelt, das von der JSON-Struktur definiert und mithilfe der $.parseJSON()Methode analysiert wird.


12

Nur zum Spaß, hier ist eine Möglichkeit, eine Funktion zu verwenden:

 jsonObject = (new Function('return ' + jsonFormatData))()

1
Interessanter Ansatz, ich bin mir nicht sicher, ob ich diesen mit JSON.Parse verwenden würde, aber es ist schön zu sehen, dass jemand über den Tellerrand hinaus denkt.

5
Dies ist sehr ähnlich zu der Verwendung evalund nicht sicher. : P
Florrie

7
Dies hat alle Nachteile der Verwendung eval, ist jedoch für die Betreuer komplizierter und schwieriger zu verstehen.
Quentin

9

Verwenden JSON.parseist wahrscheinlich der beste Weg.

Hier ist ein Beispiel für eine Live-Demo .

var jsonRes = '{ "students" : [' +
          '{ "firstName":"Michel" , "lastName":"John" ,"age":18},' +
          '{ "firstName":"Richard" , "lastName":"Joe","age":20 },' +
          '{ "firstName":"James" , "lastName":"Henry","age":15 } ]}';
var studentObject = JSON.parse(jsonRes);

9

Der einfachste Weg mit der parse()Methode:

var response = '{"result":true,"count":1}';
var JsonObject= JSON.parse(response);

Dann können Sie die Werte der JSON-Elemente abrufen, zum Beispiel:

var myResponseResult = JsonObject.result;
var myResponseCount = JsonObject.count;

Verwenden von jQuery wie in der jQuery.parseJSON()Dokumentation beschrieben:

JSON.parse(jsonString);

9

Versuchen Sie, die Methode mit diesem Datenobjekt zu verwenden. Beispiel: Data='{result:true,count:1}'

try {
  eval('var obj=' + Data);
  console.log(obj.count);
}
catch(e) {
  console.log(e.message);
}

Diese Methode hilft in Nodejs wirklich, wenn Sie mit der seriellen Port-Programmierung arbeiten


Es ist wirklich lustig, wie die Leute auf "Eval is Evil" fixiert sind und alles tun, um dies zu vermeiden, und sogar die gesamte Eval-Funktionalität neu schreiben.
Diynevala

Ist Konsens dieser Trick eine sichere Methode, um Zeichenfolge in JSON-Objekt umzuwandeln? Ich könnte dies verwenden, da keine zusätzlichen js-Importe erforderlich sind.
Wen

1
JEDER Ansatz mit evaloder Functionist gleichermaßen anfällig
Slai

undefined; function bye() {...} bye();
Salvioner

5

Ich habe einen "besseren" Weg gefunden:

In CoffeeScript:

try data = JSON.parse(jqxhr.responseText)
data ||= { message: 'Server error, please retry' }

In Javascript:

var data;

try {
  data = JSON.parse(jqxhr.responseText);
} catch (_error) {}

data || (data = {
  message: 'Server error, please retry'
});

4

JSON-Analyse ist immer ein Schmerz. Wenn die Eingabe nicht wie erwartet ist, wird ein Fehler ausgegeben und es stürzt ab, was Sie tun.

Sie können die folgende winzige Funktion verwenden, um Ihre Eingabe sicher zu analysieren. Es wird immer ein Objekt gedreht, auch wenn die Eingabe ungültig ist oder bereits ein Objekt ist, das in den meisten Fällen besser ist:

JSON.safeParse = function (input, def) {
  // Convert null to empty object
  if (!input) {
    return def || {};
  } else if (Object.prototype.toString.call(input) === '[object Object]') {
    return input;
  }
  try {
    return JSON.parse(input);
  } catch (e) {
    return def || {};
  }
};

Object.prototype.toString.call(input) === '[object Object]'sollte typeof input === 'object'IMO sein
Serge K.

typeof input gibt auch ein Objekt für null und Arrays zurück. Es ist also nicht der sichere Weg, dies zu tun.
Tahsin Turkoz

Sie haben den nullFall bereits zuvor behandelt, und ein Array ist ein Objekt. Wenn Sie es testen möchten, können Sie verwenden instanceof. Wenn Sie dieser Funktion eine geben Array, wird sie außerdem abfangen und return defwenn sie das perfekt feine Array hätte zurückgeben können.
Serge K.

In meinem Kommentar ging es um einen gesunden Menschenverstand beim Fangen von Objekten. Meine Funktion kann mehrere Vorbeugungen haben, aber die Verwendung von Eingabetypen ist im Allgemeinen nicht die bevorzugte Methode zum Erkennen von Objekten.
Tahsin Turkoz

IMO, der gesunde Menschenverstand verwendet keine toString()Methode, um zu überprüfen, ob eine Variable ein Objekt ist oder nicht. Siehe AngularJS , jQuery , Underscore oder sogar Entwickler
Serge K.


3

Wenn wir eine Zeichenfolge wie diese haben:

"{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"

dann können wir JSON.parsediese Zeichenfolge einfach zweimal in ein JSON-Objekt konvertieren:

var sampleString = "{\"status\":1,\"token\":\"65b4352b2dfc4957a09add0ce5714059\"}"
var jsonString= JSON.parse(sampleString)
var jsonObject= JSON.parse(jsonString)

Und wir können Werte aus dem JSON-Objekt extrahieren, indem wir:

// instead of last JSON.parse:
var { status, token } = JSON.parse(jsonString);

Das Ergebnis wird sein:

status = 1 and token = 65b4352b2dfc4957a09add0ce5714059

3

JSON.parse() konvertiert jede an die Funktion übergebene JSON-Zeichenfolge in ein JSON-Objekt.

Um es besser zu verstehen, drücken Sie F12, um "Inspect Element" in Ihrem Browser zu öffnen, und gehen Sie zur Konsole, um die folgenden Befehle zu schreiben:

var response = '{"result":true,"count":1}'; //sample json object(string form)
JSON.parse(response); //converts passed string to JSON Object.

Führen Sie nun den folgenden Befehl aus:

console.log(JSON.parse(response));

Sie erhalten eine Ausgabe als Objekt {result: true, count: 1}.

Um dieses Objekt zu verwenden, können Sie es der Variablen zuweisen, vielleicht obj:

var obj = JSON.parse(response);

Mit objdem .Operator dot ( ) können Sie auf Eigenschaften des JSON-Objekts zugreifen.

Versuchen Sie, den Befehl auszuführen:

console.log(obj.result);

3

Offizielle Dokumentation :

Die JSON.parse()Methode analysiert eine JSON-Zeichenfolge und erstellt den durch die Zeichenfolge beschriebenen JavaScript-Wert oder das beschriebene Objekt. Eine optionale reviverFunktion kann bereitgestellt werden, um eine Transformation für das resultierende Objekt durchzuführen, bevor es zurückgegeben wird.

Syntax:

JSON.parse(text[, reviver])

Parameter:

text : Die Zeichenfolge, die als JSON analysiert werden soll. Eine Beschreibung der JSON-Syntax finden Sie im JSON-Objekt.

reviver (optional) : Wenn es sich um eine Funktion handelt, wird festgelegt, wie der ursprünglich durch Parsen erzeugte Wert transformiert wird, bevor er zurückgegeben wird.

Rückgabewert

Das Objekt, das dem angegebenen JSON-Text entspricht.

Ausnahmen

Löst eine SyntaxError-Ausnahme aus, wenn die zu analysierende Zeichenfolge kein gültiges JSON ist.



2

Analysieren Sie die JSON-Zeichenfolge mit JSON.parse(), und die Daten werden zu einem JavaScript-Objekt:

JSON.parse(jsonString)

Hier steht JSON für die Verarbeitung des JSON-Datasets.

Stellen Sie sich vor, wir haben diesen Text von einem Webserver erhalten:

'{ "name":"John", "age":30, "city":"New York"}'

So analysieren Sie ein JSON-Objekt:

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}'); 

Hier objist das jeweilige JSON-Objekt, das so aussieht:

{ "name":"John", "age":30, "city":"New York"}

Um einen Wert abzurufen, verwenden Sie den .Operator:

obj.name // John
obj.age //30

Konvertieren Sie ein JavaScript-Objekt in eine Zeichenfolge mit JSON.stringify().


1

Nur zum Cover Parse für verschiedene Eingabetypen

Analysieren Sie die Daten mit JSON.parse (), und die Daten werden zu einem JavaScript-Objekt.

var obj = JSON.parse('{ "name":"John", "age":30, "city":"New York"}');

Wenn Sie JSON.parse () für einen von einem Array abgeleiteten JSON verwenden, gibt die Methode anstelle eines JavaScript-Objekts ein JavaScript-Array zurück.

var myArr = JSON.parse(this.responseText);
console.log(myArr[0]);

Datumsobjekte sind in JSON nicht zulässig. Für Dates mache so etwas

var text = '{ "name":"John", "birth":"1986-12-14", "city":"New York"}';
var obj = JSON.parse(text);
obj.birth = new Date(obj.birth);

Funktionen sind in JSON nicht zulässig. Wenn Sie eine Funktion einfügen müssen, schreiben Sie sie als Zeichenfolge.

var text = '{ "name":"John", "age":"function () {return 30;}", "city":"New York"}';
var obj = JSON.parse(text);
obj.age = eval("(" + obj.age + ")");

0

Ältere Frage, ich weiß, aber niemand bemerkt diese Lösung durch die Verwendung new Function()einer anonymen Funktion, die die Daten zurückgibt.


Nur ein Beispiel:

 var oData = 'test1:"This is my object",test2:"This is my object"';

 if( typeof oData !== 'object' )
  try {
   oData = (new Function('return {'+oData+'};'))();
  }
  catch(e) { oData=false; }

 if( typeof oData !== 'object' )
  { alert( 'Error in code' ); }
 else {
        alert( oData.test1 );
        alert( oData.test2 );
      }

Dies ist etwas sicherer, da es innerhalb einer Funktion ausgeführt wird und nicht direkt in Ihrem Code kompiliert wird. Wenn sich also eine Funktionsdeklaration darin befindet, wird sie nicht an das Standardfensterobjekt gebunden.

Ich verwende dies, um Konfigurationseinstellungen von DOM-Elementen (zum Beispiel das Datenattribut) einfach und schnell zu "kompilieren".


0

Zusammenfassung:

Javascript (sowohl Browser als auch NodeJS) verfügt über ein integriertes JSONObjekt. Auf diesem Objekt befinden sich 2 bequeme Methoden für den Umgang mit JSON. Sie sind die folgenden:

  1. JSON.parse() Nimmt JSONals Argument, gibt JS-Objekt zurück
  2. JSON.stringify() Nimmt das JS-Objekt als Argument und gibt das JSONObjekt zurück

Andere Anwendungen:

Außerdem können sie für den sehr bequemen Umgang mit JSONihnen für andere Mittel verwendet werden. Die Kombination beider JSONMethoden ermöglicht es uns, sehr einfach tiefe Klone von Arrays oder Objekten zu erstellen. Zum Beispiel:

let arr1 = [1, 2, [3 ,4]];
let newArr = arr1.slice();

arr1[2][0] = 'changed'; 
console.log(newArr); // not a deep clone

let arr2 = [1, 2, [3 ,4]];
let newArrDeepclone = JSON.parse(JSON.stringify(arr2));

arr2[2][0] = 'changed'; 
console.log(newArrDeepclone); // A deep clone, values unchanged


0

Sie können auch die reviverFunktion zum Filtern verwenden.

var data = JSON.parse(jsonString, function reviver(key, value) {
   //your code here to filter
});

Weitere Informationen finden Sie unter JSON.parse.


0

JSON.parse ist der richtige Weg, um eine Zeichenfolge in ein Objekt zu konvertieren. Wenn die analysierte Zeichenfolge jedoch kein Objekt ist oder wenn die Zeichenfolge nicht korrekt ist, wird ein Fehler ausgegeben, der dazu führt, dass der Rest des Codes beschädigt wird Ideal, um die JSON.parse-Funktion wie in try-catch zu verpacken

try{
   let obj = JSON.parse(string);
}catch(err){
   console.log(err);
}

-1

Versuchen Sie dies. Dieses ist in Typoskript geschrieben.

         export function safeJsonParse(str: string) {
               try {
                 return JSON.parse(str);
                   } catch (e) {
                 return str;
                 }
           }

Ich bin neu in Typescript. Welchen Nutzen bringt dies JSON.parse()?
Marc L.

Wenn eine Ausnahme aufgetreten ist, wird die Eingabezeichenfolge selbst zurückgegeben
Supun Dharmarathne

-1
/**
 * Safely turning a JSON string into an object
 *
 * @param {String} str - JSON String
 * @returns deserialized object, false if error
 */
export function jsonParse(str) {
  let data = null;
  try {
    data = JSON.parse(str);
  } catch (err) {
    return false;
  }
  return data;
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.