Wie kann ich überprüfen, ob ein Wert ein JSON-Objekt ist?

101

Mein serverseitiger Code gibt einen Wert zurück, der bei Erfolg ein JSON-Objekt und bei einem Fehler eine Zeichenfolge 'false' ist. Wie kann ich nun überprüfen, ob der zurückgegebene Wert ein JSON-Objekt ist?

Bart
quelle
2
Wenn es sich tatsächlich um "Ihren" serverseitigen Code handelt, warum nicht ein Statusfeld im JSON-Ergebnis haben, anstatt diese "manchmal-es-JSON-und-manchmal-ist-es-nicht" -Situation zu erstellen ...?
HostileFork sagt, vertraue SE
@ Hostile Aus Debugging-Gründen. Sie wissen jetzt nie, welche Art von Fehler der Server auslösen wird, und zu diesem Zeitpunkt wird json nicht verwendet.
Bart
1
Ich sehe immer noch nicht, wie ein Fehlercode (als benanntes Feld) in der Serverantwort dies untergraben würde. Es ist gut genug für Freebase! wiki.freebase.com/wiki/MQL_errors
HostileFork sagt, vertraue SE
Bitte ändern Sie die akzeptierte Antwort in Serguei Federovs, wenn Sie können, ist die aktuell akzeptierte Antwort falsch.
Serj Sagan
Was ist ein "JSON-Objekt"? Es gibt JSON-Zeichenfolgen und JS-Objekte, aber es gibt kein "JavaScript-Objektnotationsobjekt".
Mpen

Antworten:

105

jQuery.parseJSON () sollte ein Objekt vom Typ "object" zurückgeben, wenn die Zeichenfolge JSON war, sodass Sie nur den Typ mit überprüfen müssen typeof

var response=jQuery.parseJSON('response from server');
if(typeof response =='object')
{
  // It is JSON
}
else
{
  if(response ===false)
  {
     // the response was a string "false", parseJSON will convert it to boolean false
  }
  else
  {
    // the response was something else
  }
}
Dr.Molle
quelle
29
Möglicherweise muss auch ein try / catch für Ausnahmen verwendet werden, wenn es möglich ist, dass parseJSON sich mit etwas anderem als JSON-Werten (dh HTML) befasst
acorncom
2
Vor jQuery 1.9 gab $ .parseJSON null zurück, anstatt einen Fehler auszulösen, wenn eine leere Zeichenfolge, null oder undefiniert übergeben wurde, obwohl diese JSON nicht gültig sind. jquery site link
gloomy.penguin
7
Diese Lösung ist nicht die beste, weil Rückgabefehler "SyntaxError: JSON.parse: unexpected character"! Ich denke, die beste Lösung ist die Verwendung von try / catch, die Serguei Fedorovhier angegeben ist: stackoverflow.com/questions/4295386/…
Nabi KAZ
2
Wenn Sie jquery nicht verwenden möchten, können Sie Vanilla JS verwenden, indem Sie den Konstruktortyp wie hier beschrieben überprüfen: stackoverflow.com/questions/11182924/…
Mat
2
Diese Antwort ist falsch, die Antwort von Serguei Federov sollte die akzeptierte Antwort sein.
Serj Sagan
148

Die gewählte Lösung funktioniert bei mir eigentlich nicht, weil ich eine bekomme

     "Unexpected Token <" 

Fehler in Chrome. Dies liegt daran, dass der Fehler ausgelöst wird, sobald die Analyse auf ein unbekanntes Zeichen stößt. Es gibt jedoch eine Möglichkeit, dies zu umgehen, wenn Sie nur Zeichenfolgenwerte über Ajax zurückgeben (was sehr nützlich sein kann, wenn Sie PHP oder ASPX zum Verarbeiten von Ajax-Anforderungen verwenden und JSON je nach Bedingungen möglicherweise zurückgeben oder nicht).

Die Lösung ist recht einfach. Sie können Folgendes tun, um zu überprüfen, ob es sich um eine gültige JSON-Rückgabe handelt

       var IS_JSON = true;
       try
       {
               var json = $.parseJSON(msg);
       }
       catch(err)
       {
               IS_JSON = false;
       }                

Wie ich bereits sagte, ist dies die Lösung, wenn Sie entweder Zeichenfolgentyp von Ihrer AJAX-Anforderung zurückgeben oder wenn Sie gemischten Typ zurückgeben.

Serguei Fedorov
quelle
Die Frage bezieht sich zu keinem Zeitpunkt auf Nicht-JSON-Zeichenfolgen. Der Server gibt immer einen gültigen JSON zurück (eine Zeichenfolge falseist auch ein gültiger JSON). Die Frage ist nur um einen einzigen Punkt: Wie zu unterscheiden , ob der geparste JSON-String ist ein boolean falseoder eine Objekt
Dr.Molle
2
Leistungsüberlegung: Wenn Sie dies in eine Funktion einschließen, stellen Sie sicher, dass Sie den JSON nicht zweimal analysieren (einmal im Try-Catch und einmal im Code, der die Funktion aufruft).
Michiel Cornille
Es ist eine Hilfefunktion isJSON () , die Sie verwenden können : isJSON(someValue).
Chofoteddy
19

Lösung 3 (schnellster Weg)

/**
 * @param Object
 * @returns boolean
 */
function isJSON (something) {
    if (typeof something != 'string')
        something = JSON.stringify(something);

    try {
        JSON.parse(something);
        return true;
    } catch (e) {
        return false;
    }
}

Du kannst es benutzen:

var myJson = [{"user":"chofoteddy"}, {"user":"bart"}];
isJSON(myJson); // true

Der beste Weg, um zu überprüfen, ob ein Objekt vom Typ JSON oder Array ist, ist wie folgt:

var a = [],
    o = {};

Lösung 1

toString.call(o) === '[object Object]'; // true
toString.call(a) === '[object Array]'; // true

Lösung 2

a.constructor.name === 'Array'; // true
o.constructor.name === 'Object'; // true

Genau genommen ist ein Array jedoch Teil einer JSON-Syntax. Daher sind die folgenden zwei Beispiele Teil einer JSON-Antwort:

console.log(response); // {"message": "success"}
console.log(response); // {"user": "bart", "id":3}

Und:

console.log(response); // [{"user":"chofoteddy"}, {"user":"bart"}]
console.log(response); // ["chofoteddy", "bart"]

AJAX / JQuery (empfohlen)

Wenn Sie JQuery verwenden, um Informationen über AJAX zu bringen. Ich empfehle, dass Sie im Attribut "dataType" den Wert "json" eingeben. Wenn Sie also einen JSON erhalten oder nicht, überprüft JQuery ihn für Sie und macht ihn durch die Funktionen "success" und "error" bekannt. Beispiel:

$.ajax({
    url: 'http://www.something.com',
    data: $('#formId').serialize(),
    method: 'POST',
    dataType: 'json',
    // "sucess" will be executed only if the response status is 200 and get a JSON
    success: function (json) {},
    // "error" will run but receive state 200, but if you miss the JSON syntax
    error: function (xhr) {}
});
Chofoteddy
quelle
13

Wenn Sie über jQuery verfügen, verwenden Sie isPlainObject .

if ($.isPlainObject(my_var)) {}
Knie
quelle
5
Wenn Sie isPlainObject für eine Zeichenfolge verwenden, wird false zurückgegeben, z. B. jQuery.isPlainObject ('{}')
Roy Shoa,
Noch wichtiger ist, dass diese Funktion nach den Dokumenten immer noch zurückgegeben wird, wenn sie einen nicht JSON-ähnlichen Wert als Eigenschaft enthält true.
Samvv
6
var checkJSON = function(m) {

   if (typeof m == 'object') { 
      try{ m = JSON.stringify(m); }
      catch(err) { return false; } }

   if (typeof m == 'string') {
      try{ m = JSON.parse(m); }
      catch (err) { return false; } }

   if (typeof m != 'object') { return false; }
   return true;

};


checkJSON(JSON.parse('{}'));      //true
checkJSON(JSON.parse('{"a":0}')); //true
checkJSON('{}');                  //true
checkJSON('{"a":0}');             //true
checkJSON('x');                   //false
checkJSON('');                    //false
checkJSON();                      //false
luizhp
quelle
4

Da es sich nur um ein falsches und ein json-Objekt handelt, überprüfen Sie nicht, ob es falsch ist. Andernfalls muss es sich um ein json-Objekt handeln.

if(ret == false || ret == "false") {
    // json
}
Andreas Wong
quelle
2

Ich weiß, dass dieser Thread bereits beantwortet wurde, aber hierher zu kommen hat meine Probleme nicht wirklich gelöst. Ich habe diese Funktion woanders gefunden. Vielleicht wird jemand, der hierher kommt, feststellen, dass es für ihn von Nutzen ist.

function getClass(obj) {
  if (typeof obj === "undefined")
    return "undefined";
  if (obj === null)
    return "null";
  return Object.prototype.toString.call(obj)
    .match(/^\[object\s(.*)\]$/)[1];
}
pythonian29033
quelle
1
var data = 'json string ?';
var jdata = null;
try
{
    jdata = $.parseJSON(data);  
}catch(e)
{}

if(jdata)
{
//use jdata
}else
{
//use data
}
Firas Abd Alrahman
quelle
0

Wenn Sie explizit auf gültigen JSON testen möchten (im Gegensatz zum Fehlen des zurückgegebenen Werts false), können Sie einen hier beschriebenen Parsing-Ansatz verwenden .

Ken Redler
quelle
0

Ich mag die akzeptierte Antwort nicht wirklich. In erster Linie erfordert es jQuery, das nicht immer verfügbar oder erforderlich ist. Zweitens führt es eine vollständige Stringifizierung des Objekts durch, was für mich übertrieben ist. Hier ist eine einfache Funktion, die gründlich erkennt, ob ein Wert JSON-ähnlich ist, und aus Gründen der Allgemeinheit nur einige Teile der lodash- Bibliothek verwendet.

import * as isNull from 'lodash/isNull'
import * as isPlainObject from 'lodash/isPlainObject'
import * as isNumber from 'lodash/isNumber'
import * as isBoolean from 'lodash/isBoolean'
import * as isString from 'lodash/isString'
import * as isArray from 'lodash/isArray'

function isJSON(val) {
  if (isNull(val)
   || isBoolean(val)
   || isString(val))
    return true;
  if (isNumber(val)) 
     return !isNaN(val) && isFinite(val)
  if (isArray(val))
    return Array.prototype.every.call(val, isJSON)
  if (isPlainObject(val)) {
    for (const key of Object.keys(val)) {
      if (!isJSON(val[key]))
        return false
    }
    return true
  }
  return false
}

Ich habe mir sogar die Zeit genommen, es in npm als Paket zu veröffentlichen: https://npmjs.com/package/is-json-object . Verwenden Sie es zusammen mit etwas wie Webpack , um es in den Browser zu bekommen.

Hoffe das hilft jemandem!

samvv
quelle
0

Ich verwende dies, um JSON-Objekt zu validieren

function isJsonObject(obj) {
    try {
        JSON.parse(JSON.stringify(obj));
    } catch (e) {
        return false;
    }
    return true;
}

Ich benutze dies, um JSON String zu validieren

function isJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
Abhishek Goel
quelle
0

Ich habe alle vorgeschlagenen Antworten ausprobiert, nichts hat bei mir funktioniert, also musste ich verwenden

jQuery.isEmptyObject()

Hacke, die jemand anderem bei diesem Problem hilft

Jay Rizzi
quelle
-1

Sie sollten json immer zurückgeben , aber seinen Status ändern oder im folgenden Beispiel die ResponseCode- Eigenschaft:

if(callbackResults.ResponseCode!="200"){
    /* Some error, you can add a message too */
} else {
    /* All fine, proceed with code */
};
kobe
quelle
@bart, Sie können das Objekt einfach in der if-Bedingung bereitstellen, die die Prüfung durchführt.
Kobe