AJAX: Überprüfen Sie, ob eine Zeichenfolge JSON ist?

83

Mein JavaScript stürzt manchmal in dieser Zeile ab:

var json = eval('(' + this.responseText + ')');

Abstürze werden verursacht, wenn das Argument von eval()nicht JSON ist. Gibt es eine Möglichkeit zu überprüfen, ob die Zeichenfolge JSON ist, bevor dieser Aufruf ausgeführt wird?

Ich möchte kein Framework verwenden - gibt es eine Möglichkeit, diese Funktion nur mit zu erstellen eval()? (Es gibt einen guten Grund, das verspreche ich.)

Nick Heiner
quelle
Sie könnten versuchen, JSON.parse () in einem try / catch zu verwenden ... Wenn Sie zu catch gelangen, ist das JSON-Markup ungültig. Das ist natürlich irgendwie ineffizient, heh ... Können Sie mir ein Beispiel für das ungültige JSON-Markup geben, das Sie erhalten?
Warty

Antworten:

157

Wenn Sie den JSON-Parser von json.org einschließen, können Sie seine parse () -Funktion verwenden und ihn einfach wie folgt in einen try / catch-Befehl einschließen:

try
{
   var json = JSON.parse(this.responseText);
}
catch(e)
{
   alert('invalid json');
}

So etwas würde wahrscheinlich tun, was Sie wollen.

brettkelly
quelle
9
Mit jQuery.parseJSON (..) müssten Sie json.org
RayLoveless
1
@Raymo OP erwähnte nicht, dass jQuery und json2.js weniger als die Hälfte der Größe von jQuery (in Bezug auf die Dateigröße) verwenden.
brettkelly
Das Parsen einer ganzen Zeichenfolge ist eine schlechte Praxis, und das Auslösen einer Ausnahme kann zu Verzögerungen führen
duftend am
Es wird keine Ausnahme auslösen, wenn Sie eine Zahlenfolge senden
Hesham Yassin
21

Ihre ist die jQuery-Alternative ...

try
{
  var jsonObject = jQuery.parseJSON(yourJsonString);
}
catch(e)
{
  // handle error 
}
RayLoveless
quelle
15

Ich empfehle dringend, eine Javascript-JSON-Bibliothek für die Serialisierung von und nach JSON zu verwenden. eval()ist ein Sicherheitsrisiko, das niemals verwendet werden sollte, es sei denn, Sie sind absolut sicher, dass seine Eingabe hygienisch und sicher ist.

Wenn eine JSON-Bibliothek vorhanden ist, schließen Sie den Aufruf einfach parse()in einen try / catch-Block ein, um Nicht-JSON-Eingaben zu verarbeiten:

try
{
  var jsonObject = JSON.parse(yourJsonString);
}
catch(e)
{
  // handle error 
}
Håvard S.
quelle
2

Vielleicht hilft das: Mit diesem Code können Sie Ihre Daten direkt abrufen ...

<!DOCTYPE html>
<html>
<body>

<h3>Open console, please, to view result!</h3>
<p id="demo"></p>

<script>
var tryJSON = function (test) {
	try {
	    JSON.parse(test);
	}
	catch(err) {
    	// maybe you need to escape this… (or not)
	    test = '"'+test.replace(/\\?"/g,'\\"')+'"';
	}
	eval('test = '+test);
	console.debug('Try json:', test);
};

// test with string…
var test = 'bonjour "mister"';
tryJSON(test);
// test with JSON…
var test = '{"fr-FR": "<p>Ceci est un texte en français !</p>","en-GB": "<p>And here, a text in english!</p>","nl-NL": "","es-ES": ""}';
tryJSON(test);
</script>

</body>
</html>

Dujardin Emmanuel
quelle
Es gibt viele alternative Möglichkeiten, um das gleiche Ergebnis zu erzielen. Die Verwendung von eval () ist wahrscheinlich die am wenigsten geeignete.
David
0

Das Problem mit je nach try-catchAnsatz ist, dass JSON.parse('123') = 123es keine Ausnahme auslöst. Daher try-catchmüssen wir zusätzlich zu dem den Typ wie folgt überprüfen:

function isJsonStr(str) {
    var parsedStr = str;
    try {
        parsedStr = JSON.parse(str);
    } catch (e) {
        return false;
    }
    return typeof parsedStr == 'object'
}
Hesham Yassin
quelle
0

Warum können Sie nicht einfach überprüfen, wie die Antwort lautet? Es ist effizienter.

var result;

if (response.headers['Content-Type'] === 'application/json')
    result = JSON.parse(this.responseText);
else
    result = this.responseText;

screen1

EINGESTEHEN
quelle
-1

Es gibt eine winzige Bibliothek, die JavaScript-Typen überprüft: is.js.

is.json({foo: 'bar'});
=> true

// functions are returning as false
is.json(toString);
=> false

is.not.json([]);
=> true

is.all.json({}, 1);
=> false

is.any.json({}, 2);
=> true

// 'all' and 'any' interfaces can also take array parameter
is.all.json([{}, {foo: 'bar'}]);
=> true

Eigentlich ist is.js viel mehr als das, einige ehrenwerte Erwähnungen:

var obj = document.createElement('div');
is.domNode(obj);
=> true

is.error(new Error());
=> true

is.function(toString);
=> true

is.chrome();
=> true if current browser is chrome

Ramazan Polat
quelle