Come posso verificare se un valore è un oggetto json?


101

Il mio codice lato server restituisce un valore che è un oggetto json in caso di successo e una stringa "false" in caso di errore. Ora come posso verificare se il valore restituito è un oggetto json?


2
Se è effettivamente il "tuo" codice lato server, perché non avere un campo di stato nel risultato JSON invece di creare questa situazione "a volte-è-JSON-e-a-volte-non-è" ...?
HostileFork dice di non fidarsi di SE

@Hostile Per motivi di debug. Non sai mai quale tipo di errore verrà generato dal server ea quel punto json non viene utilizzato.
Bart

1
Ancora non vedo come avere un codice di errore (come un campo denominato) nella risposta del server possa comprometterlo. È abbastanza buono per Freebase! wiki.freebase.com/wiki/MQL_errors
HostileFork dice di non fidarsi di SE il

Si prega di cambiare la risposta accettata a Serguei Federov, se è possibile la risposta attualmente accettata non è corretta.
Serj Sagan

Cos'è un "oggetto json"? Esistono stringhe JSON e oggetti JS, ma non esiste un "oggetto Notazione oggetto JavaScript".
mpen

Risposte:


105

jQuery.parseJSON () dovrebbe restituire un oggetto di tipo "oggetto", se la stringa era JSON, quindi devi solo controllare il tipo con 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
  }
}

29
Potrebbe anche essere necessario utilizzare un try / catch per le eccezioni se è possibile che parseJSON abbia a che fare con qualcosa di diverso dai valori JSON (ovvero HTML)
acorncom

2
Prima di jQuery 1.9, $ .parseJSON restituiva null invece di generare un errore se veniva passata una stringa vuota, null o undefined, anche se non sono JSON validi. link al sito jquery
gloomy.penguin

7
Questa soluzione non è la migliore, perché "SyntaxError: JSON.parse: unexpected character"errore di ritorno ! , Penso che la soluzione migliore sia usare try / catch che ha detto Serguei Fedorovqui: stackoverflow.com/questions/4295386/…
Nabi KAZ

2
Se non vuoi usare jquery, puoi usare JS vanilla controllando il tipo di costruttore come descritto qui: stackoverflow.com/questions/11182924/…
Mat

2
Questa risposta non è corretta, la risposta di Serguei Federov dovrebbe essere la risposta accettata.
Serj Sagan

148

La soluzione scelta in realtà non funziona per me perché ottengo un

     "Unexpected Token <" 

errore in Chrome. Questo perché l'errore viene generato non appena l'analisi viene rilevata e un carattere sconosciuto. Tuttavia, c'è un modo per aggirare questo se stai restituendo solo valori di stringa tramite ajax (che può essere abbastanza utile se stai usando PHP o ASPX per elaborare le richieste ajax e potresti o meno restituire JSON a seconda delle condizioni)

La soluzione è abbastanza semplice, puoi fare quanto segue per verificare se si trattava di un ritorno JSON valido

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

Come ho detto prima, questa è la soluzione se stai restituendo materiale di tipo stringa dalla tua richiesta AJAX o se stai restituendo un tipo misto.


La domanda non riguarda le stringhe non JSON in nessun punto. Il server restituisce sempre un JSON valido (anche una stringa falseè JSON valido). La domanda riguarda solo un singolo punto: come distinguere se la stringa JSON analizzata è un booleano falseo un oggetto
Dottor Molle

2
Considerazione sulle prestazioni: racchiudendo questo in una funzione, assicurati di non analizzare il json due volte (una volta all'interno del try catch e una volta nel codice che chiama la funzione.)
Michiel Cornille

E 'un aiutanti funzione isJSON () che è possibile utilizzare: isJSON(someValue).
Chofoteddy

19

Soluzione 3 (modo più veloce)

/**
 * @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;
    }
}

Puoi usarlo:

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

Il modo migliore per verificare che un oggetto sia di tipo JSON o array è il seguente:

var a = [],
    o = {};

Soluzione 1

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

Soluzione 2

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

Ma, in senso stretto, un array fa parte di una sintassi JSON. Pertanto, i due esempi seguenti fanno parte di una risposta JSON:

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

E:

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

AJAX / JQuery (consigliato)

Se usi JQuery per portare informazioni tramite AJAX. Ti consiglio di inserire nell'attributo "dataType" il valore "json", in questo modo se ottieni o meno un JSON, JQuery lo convalidi per te e lo fai conoscere attraverso le loro funzioni "successo" ed "errore". Esempio:

$.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) {}
});

13

Se hai jQuery, usa isPlainObject .

if ($.isPlainObject(my_var)) {}

5
Se usi isPlainObject su una stringa, restituisce false, ad esempio jQuery.isPlainObject ('{}')
Roy Shoa

Ancora più importante, se contiene un valore non simile a JSON come proprietà, secondo i documenti questa funzione restituirà comunque 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

4

Dato che è solo un oggetto falso e json, perché non controlli se è falso, altrimenti deve essere json.

if(ret == false || ret == "false") {
    // json
}

2

So che a questo thread è già stata data risposta, ma venire qui non ha risolto i miei problemi, ho trovato questa funzione da qualche altra parte. forse qualcuno che viene qui troverà che sia di qualche utilità per loro;

function getClass(obj) {
  if (typeof obj === "undefined")
    return "undefined";
  if (obj === null)
    return "null";
  return Object.prototype.toString.call(obj)
    .match(/^\[object\s(.*)\]$/)[1];
}

1
var data = 'json string ?';
var jdata = null;
try
{
    jdata = $.parseJSON(data);  
}catch(e)
{}

if(jdata)
{
//use jdata
}else
{
//use data
}

0

Se vuoi testare in modo esplicito per JSON valido (al contrario dell'assenza del valore restituito false), puoi utilizzare un approccio di analisi come descritto qui .


0

Non mi piace molto la risposta accettata. Innanzitutto richiede jQuery, che non è sempre disponibile o richiesto. In secondo luogo, esegue una completa stringificazione dell'oggetto che per me è eccessiva. Ecco una semplice funzione che rileva accuratamente se un valore è simile a JSON, utilizzando nient'altro che alcune parti della libreria lodash per la genericità.

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
}

Mi sono persino preso il tempo di metterlo in npm come pacchetto: https://npmjs.com/package/is-json-object . Usalo insieme a qualcosa come Webpack per ottenerlo nel browser.

Spero che questo aiuti qualcuno!


0

Lo sto usando per convalidare l'oggetto JSON

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

Lo sto usando per convalidare la stringa JSON

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

0

ho provato tutte le risposte suggerite, niente ha funzionato per me, quindi ho dovuto usare

jQuery.isEmptyObject()

zappa che aiuta qualcun altro con questo problema


-1

È necessario restituire sempre json , ma modificarne lo stato o, nell'esempio seguente, la proprietà ResponseCode :

if(callbackResults.ResponseCode!="200"){
    /* Some error, you can add a message too */
} else {
    /* All fine, proceed with code */
};

@ bart, puoi semplicemente fornire l'oggetto nella condizione if, che farà il controllo.
Kobe
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.