Comment puis-je vérifier si une valeur est un objet json?

101

Mon code côté serveur renvoie une valeur qui est un objet json en cas de succès et une chaîne «false» en cas d'échec. Maintenant, comment puis-je vérifier si la valeur retournée est un objet json?

bart
la source
2
S'il s'agit en fait de "votre" code côté serveur, pourquoi ne pas avoir un champ d'état dans le résultat JSON plutôt que de créer cette situation "parfois-c'est-JSON-et-parfois-ce-n'est-pas" ...?
HostileFork dit de ne pas faire confiance à SE
@Hostile Pour des raisons de débogage. Vous ne savez jamais quel type de panne le serveur lancera et à ce stade, json n'est pas utilisé.
bart
1
Je ne vois toujours pas en quoi le fait d'avoir un code d'erreur (en tant que champ nommé) dans la réponse du serveur nuirait à cela. C'est assez bon pour Freebase! wiki.freebase.com/wiki/MQL_errors
HostileFork dit de ne pas faire confiance à SE
Veuillez remplacer la réponse acceptée par celle de Serguei Federov, si vous le pouvez, la réponse actuellement acceptée est incorrecte.
Serj Sagan
Qu'est-ce qu'un "objet json"? Il existe des chaînes JSON et des objets JS, mais il n'existe pas de "objet JavaScript Object Notation".
mpen

Réponses:

105

jQuery.parseJSON () doit renvoyer un objet de type "object", si la chaîne était JSON, il vous suffit donc de vérifier le type avec 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
la source
29
Pourrait également avoir besoin d'utiliser un try / catch pour les exceptions s'il est possible que parseJSON va traiter autre chose que des valeurs JSON (c'est-à-dire HTML)
acorncom
2
Avant jQuery 1.9, $ .parseJSON renvoyait null au lieu de renvoyer une erreur s'il était passé une chaîne vide, null ou non définie, même si ceux-ci ne sont pas des JSON valides. lien du site jquery
gloomy.penguin
7
Cette solution n'est pas la meilleure, car retourne une "SyntaxError: JSON.parse: unexpected character"erreur! , Je pense que la meilleure solution est d'utiliser try / catch qui dit par Serguei Fedorovici: stackoverflow.com/questions/4295386/…
Nabi KAZ
2
Si vous ne voulez pas utiliser jquery, vous pouvez utiliser vanilla JS en vérifiant le type de constructeur comme décrit ici: stackoverflow.com/questions/11182924/...
Mat
2
Cette réponse est incorrecte, la réponse de Serguei Federov devrait être la réponse acceptée.
Serj Sagan
148

La solution choisie ne fonctionne pas vraiment pour moi car j'obtiens un

     "Unexpected Token <" 

erreur dans Chrome. C'est parce que l'erreur est lancée dès que l'analyse rencontre un caractère inconnu. Cependant, il existe un moyen de contourner ce problème si vous ne renvoyez que des valeurs de chaîne via ajax (ce qui peut être assez utile si vous utilisez PHP ou ASPX pour traiter les requêtes ajax et que vous pouvez ou non retourner JSON selon les conditions)

La solution est assez simple, vous pouvez faire ce qui suit pour vérifier s'il s'agissait d'un retour JSON valide

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

Comme je l'ai déjà dit, c'est la solution si vous retournez des éléments de type chaîne à partir de votre requête AJAX ou si vous renvoyez un type mixte.

Serguei Fedorov
la source
La question ne concerne en aucun cas les chaînes non JSON. Le serveur renvoie toujours un JSON valide (une chaîne falseest également un JSON valide). La question ne concerne qu'un seul point: comment différencier si la chaîne JSON analysée est un booléen falseou un objet
Dr.Molle
2
Considération des performances: Enveloppant cela dans une fonction, assurez-vous de ne pas analyser le json deux fois (une fois à l'intérieur de la capture d'essai et une fois dans le code qui appelle la fonction.)
Michiel Cornille
Il est une fonction des aides isJSON () que vous pouvez utiliser: isJSON(someValue).
Chofoteddy
19

Solution 3 (moyen le plus rapide)

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

Tu peux l'utiliser:

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

La meilleure façon de valider qu'un objet est de type JSON ou tableau est la suivante:

var a = [],
    o = {};

Solution 1

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

Solution 2

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

Mais, à proprement parler, un tableau fait partie d'une syntaxe JSON. Par conséquent, les deux exemples suivants font partie d'une réponse JSON:

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

Et:

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

AJAX / JQuery (recommandé)

Si vous utilisez JQuery pour apporter des informations via AJAX. Je vous recommande de mettre dans l'attribut "dataType" la valeur "json", de cette façon si vous obtenez un JSON ou non, JQuery le valide pour vous et le fait connaître à travers leurs fonctions "succès" et "erreur". Exemple:

$.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
la source
13

Si vous avez jQuery, utilisez isPlainObject .

if ($.isPlainObject(my_var)) {}
thnee
la source
5
Si vous utilisez isPlainObject sur une chaîne, il renvoie false, par exemple jQuery.isPlainObject ('{}')
Roy Shoa
Plus important encore, si elle contient une valeur non JSON en tant que propriété, selon la documentation, cette fonction sera toujours renvoyée 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
la source
4

Puisqu'il s'agit simplement d'un objet false et json, pourquoi ne pas vérifier s'il est faux, sinon ce doit être json.

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

Je sais que ce fil a déjà été répondu, mais venir ici n'a pas vraiment résolu mes problèmes, j'ai trouvé cette fonction ailleurs. peut-être que quelqu'un qui vient ici trouvera que cela leur sera utile;

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

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

Si vous souhaitez tester explicitement le JSON valide (par opposition à l'absence de la valeur renvoyée false), vous pouvez utiliser une approche d'analyse comme décrit ici .

Ken Redler
la source
0

Je n'aime pas vraiment la réponse acceptée. Tout d'abord, il nécessite jQuery, qui n'est pas toujours disponible ou requis. Deuxièmement, il fait une stringification complète de l'objet qui pour moi est exagéré. Voici une fonction simple qui détecte minutieusement si une valeur est de type JSON, en utilisant rien de plus que quelques parties de la bibliothèque lodash pour la généricité.

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
}

J'ai même pris le temps de le mettre en place dans npm sous forme de package: https://npmjs.com/package/is-json-object . Utilisez-le avec quelque chose comme Webpack pour l'obtenir dans le navigateur.

J'espère que cela aide quelqu'un!

samvv
la source
0

J'utilise ceci pour valider l'objet JSON

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

J'utilise ceci pour valider la chaîne JSON

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

j'ai essayé toutes les réponses suggérées, rien n'a fonctionné pour moi, donc j'ai dû utiliser

jQuery.isEmptyObject()

houe qui aide quelqu'un d'autre avec ce problème

Jay Rizzi
la source
-1

Vous devez toujours renvoyer json , mais modifier son état ou, dans l'exemple suivant, la propriété ResponseCode :

if(callbackResults.ResponseCode!="200"){
    /* Some error, you can add a message too */
} else {
    /* All fine, proceed with code */
};
Kobe
la source
@bart, vous pouvez simplement fournir l'objet dans la condition if, qui fera la vérification.
kobe