web-dev-qa-db-fra.com

Comment vérifier si une chaîne est une chaîne JSON valide en JavaScript sans utiliser Try/Catch

Quelque chose comme:

var jsonString = '{ "Id": 1, "Name": "Coke" }';

//should be true
IsJsonString(jsonString);

//should be false
IsJsonString("foo");
IsJsonString("<div>foo</div>")

La solution ne doit pas contenir try/catch. Certains d'entre nous activent "interrompre toutes les erreurs" et n'aiment pas que le débogueur rompt les chaînes JSON invalides.

396
Chi Chan

Un commentaire en premier. La question était de ne pas utiliser try/catch.
Si cela ne vous dérange pas de l’utiliser, lisez la réponse ci-dessous. Ici, nous vérifions simplement une chaîne JSON en utilisant une expression rationnelle, et cela fonctionnera dans la plupart des cas, mais pas dans tous les cas.

Regardez autour de la ligne 450 dans https://github.com/douglascrockford/JSON-js/blob/master/json2.js

Il y a une expression rationnelle qui recherche un JSON valide, quelque chose comme:

if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

  //the json is ok

}else{

  //the json is not ok

}

EDIT: La nouvelle version de json2.js propose une analyse plus avancée que celle ci-dessus, mais reposant toujours sur un remplacement rationnel (à partir du commentaire de @Mrchief )

151
Mic

Utilisez un analyseur JSON tel que JSON.parse:

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

Je sais que je suis 3 ans en retard à cette question, mais je me sentais comme rentrer.

Bien que la solution de Gumbo fonctionne à merveille, elle ne gère pas les cas où aucune exception n'est générée pour JSON.parse({something that isn't JSON})

Je préfère également renvoyer le JSON analysé en même temps, afin que le code d'appel n'ait pas à appeler JSON.parse(jsonString) une seconde fois.

Cela semble bien fonctionner pour mes besoins:

function tryParseJSON (jsonString){
    try {
        var o = JSON.parse(jsonString);

        // Handle non-exception-throwing cases:
        // Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
        // but... JSON.parse(null) returns null, and typeof null === "object", 
        // so we must check for that, too. Thankfully, null is falsey, so this suffices:
        if (o && typeof o === "object") {
            return o;
        }
    }
    catch (e) { }

    return false;
};
386
Matt H.
// vanillaJS
function isJSON(str) {
    try {
        return (JSON.parse(str) && !!str);
    } catch (e) {
        return false;
    }
}

Utilisation: isJSON({}) sera false, isJSON('{}') sera true.

Pour vérifier si quelque chose est une Array ou Object (parsed JSON):

// vanillaJS
function isAO(val) {
    return val instanceof Array || val instanceof Object ? true : false;
}

// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object ? true : false;

Utilisation: isAO({}) sera true, isAO('{}') sera false.

44
moeiscool

J'ai utilisé une méthode très simple pour vérifier si une chaîne était un JSON valide ou non.

function testJSON(text){
    if (typeof text!=="string"){
        return false;
    }
    try{
        JSON.parse(text);
        return true;
    }
    catch (error){
        return false;
    }
}

Résultat avec une chaîne JSON valide:

var input='["foo","bar",{"foo":"bar"}]';
testJSON(input); // returns true;

Résultat avec une chaîne simple;

var input='This is not a JSON string.';
testJSON(input); // returns false;

Résultat avec un objet:

var input={};
testJSON(input); // returns false;

Résultat avec une entrée nulle:

var input=null;
testJSON(input); // returns false;

Le dernier retourne false car le type de variable null est object.

Cela fonctionne à chaque fois. :)

15
kukko

dans le prototype js, nous avons la méthode isJSON. essayez ça 

http://api.prototypejs.org/language/string/prototype/isjson/

même http://www.prototypejs.org/learn/json

"something".isJSON();
// -> false
"\"something\"".isJSON();
// -> true
"{ foo: 42 }".isJSON();
// -> false
"{ \"foo\": 42 }".isJSON();
11
Ifi

Voici mon code de travail:

function IsJsonString(str) {
  try {
    var json = JSON.parse(str);
    return (typeof json === 'object');
  } catch (e) {
    return false;
  }
}
5
Anand Kumar

Dans le cadre du prototype String.isJSON définition ici

/**
   *  String#isJSON() -> Boolean
   *
   *  Check if the string is valid JSON by the use of regular expressions.
   *  This security method is called internally.
   *
   *  ##### Examples
   *
   *      "something".isJSON();
   *      // -> false
   *      "\"something\"".isJSON();
   *      // -> true
   *      "{ foo: 42 }".isJSON();
   *      // -> false
   *      "{ \"foo\": 42 }".isJSON();
   *      // -> true
  **/
  function isJSON() {
    var str = this;
    if (str.blank()) return false;
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
    return (/^[\],:{}\s]*$/).test(str);
  }

c'est donc la version qui peut être utilisée en passant un objet string

function isJSON(str) {
    if ( /^\s*$/.test(str) ) return false;
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
    return (/^[\],:{}\s]*$/).test(str);
  }

function isJSON(str) {
    if ( /^\s*$/.test(str) ) return false;
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
    return (/^[\],:{}\s]*$/).test(str);
  }

console.log ("this is a json",  isJSON( "{ \"key\" : 1, \"key2@e\" : \"val\"}" ) )

console.log("this is not a json", isJSON( "{ \"key\" : 1, \"key2@e\" : pippo }" ) )

4
loretoparisi

Vous pouvez utiliser la fonction javascript eval () pour vérifier si elle est valide.

par exemple.

var jsonString = '{ "Id": 1, "Name": "Coke" }';
var json;

try {
  json = eval(jsonString);
} catch (exception) {
  //It's advisable to always catch an exception since eval() is a javascript executor...
  json = null;
}

if (json) {
  //this is json
}

Vous pouvez également utiliser la fonction JSON.parse de json.org :

try {
  json = JSON.parse(jsonString);
} catch (exception) {
  json = null;
}

if (json) {
  //this is json
}

J'espère que cela t'aides.

WARNING: eval() est dangerous si quelqu'un ajoute du code JS malveillant, car il l'exécutera. Assurez-vous que la chaîne JSON est digne de confiance, c'est-à-dire que vous l'avez obtenue d'une source approuvée.

Edit Pour ma 1ère solution, il est recommandé de le faire.

 try {
      json = eval("{" + jsonString + "}");
    } catch (exception) {
      //It's advisable to always catch an exception since eval() is a javascript executor...
      json = null;
    }

Pour garantir json-ness. Si jsonString n'est pas un JSON pur, eval lève une exception.

3
Buhake Sindi

Cette réponse permet de réduire le coût de l'instruction trycatch.

J'ai utilisé JQuery pour analyser les chaînes JSON et j'ai utilisé l'instruction trycatch pour gérer les exceptions, mais le lancement d'exceptions pour les chaînes non analysables a ralenti mon code. en vérifiant sa syntaxe, j'ai utilisé la méthode habituelle en analysant la chaîne à l'aide de JQuery:

if (typeof jsonData == 'string') {
    if (! /^[\[|\{](\s|.*|\w)*[\]|\}]$/.test(jsonData)) {
        return jsonData;
    }
}

try {
    jsonData = $.parseJSON(jsonData);
} catch (e) {

}

J'ai encapsulé le code précédent dans une fonction récursive pour analyser les réponses JSON imbriquées.

3
Rabih

Je pense que je sais pourquoi tu veux éviter ça. Mais peut-être essayer et attraper! == essayer et attraper. ; o) Cela m’est venu à l’esprit:

var json_verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};

Ainsi, vous pouvez également insérer un clip sale sur l'objet JSON, par exemple:

JSON.verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};

Comme cela est aussi encapsulé que possible, il est possible qu’il ne se casse pas en cas d’erreur.

2
chrixle

Peut-être que ça va être utile:

    function parseJson(code)
{
    try {
        return JSON.parse(code);
    } catch (e) {
        return code;
    }
}
function parseJsonJQ(code)
{
    try {
        return $.parseJSON(code);
    } catch (e) {
        return code;
    }
}

var str =  "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}";
alert(typeof parseJson(str));
alert(typeof parseJsonJQ(str));
var str_b  = "c";
alert(typeof parseJson(str_b));
alert(typeof parseJsonJQ(str_b));

sortie:

IE7: chaîne , objet, chaîne, chaîne

CHROME: objet, objet, chaîne, chaîne

2
user669677
if(resp) {
    try {
        resp = $.parseJSON(resp);
        console.log(resp);
    } catch(e) {
        alert(e);
    }
}

espérons que cela fonctionne pour vous aussi

2
Darkcoder

J'en déduis à partir du commentaire d'ouverture que le cas d'utilisation définit si une réponse est HTML ou JSON. Dans ce cas, lorsque vous do recevez du JSON, vous devriez probablement l’analyser et gérer le JSON invalide à un moment donné de votre code. En plus de tout, j'imagine que vous voudriez être informé par votre navigateur si JSON est attendu mais que JSON non valide est reçu (comme le seront les utilisateurs par proxy d'un message d'erreur significatif)!

Faire une regex complète pour JSON n'est donc pas nécessaire (comme ce serait le cas, selon mon expérience, pour la plupart des cas d'utilisation). Vous feriez probablement mieux d'utiliser quelque chose comme ce qui suit:

function (someString) {
  // test string is opened with curly brace or machine bracket
  if (someString.trim().search(/^(\[|\{){1}/) > -1) {
    try { // it is, so now let's see if its valid JSON
      var myJson = JSON.parse(someString);
      // yep, we're working with valid JSON
    } catch (e) {
      // nope, we got what we thought was JSON, it isn't; let's handle it.
    }
  } else {
    // nope, we're working with non-json, no need to parse it fully
  }
}

cela devrait vous éviter d'avoir à gérer des exceptions avec un code non-JSON valide et que s'occupe de duff json en même temps.

1
Jay Edwards

var jsonstring='[{"ConnectionString":"aaaaaa","Server":"ssssss"}]';

if(((x)=>{try{JSON.parse(x);return true;}catch(e){return false}})(jsonstring)){

document.write("valide json")

}else{
document.write("invalide json")
}

1
safi eddine
function get_json(txt)
{  var data

   try     {  data = eval('('+txt+')'); }
   catch(e){  data = false;             }

   return data;
}

S'il y a des erreurs, retourne false. 

S'il n'y a pas d'erreur, retourne les données json

1
Emrah Tuncel

Voici la version TypeScript aussi:

JSONTryParse(input) {
    try {
        //check if the string exists
        if (input) {
            var o = JSON.parse(input);

            //validate the result too
            if (o && o.constructor === Object) {
                return o;
            }
        }
    }
    catch (e) {
    }

    return false;
};
0
student

Oh, vous pouvez certainement utiliser try catch pour vérifier si c'est un JSON valide ou non

Testé sur Firfox Quantom 60.0.1

utilisez function à l'intérieur d'une fonction pour obtenir le JSON testé et utilisez cette sortie pour valider la chaîne. entend un exemple.

    function myfunction(text){

       //function for validating json string
        function testJSON(text){
            try{
                if (typeof text!=="string"){
                    return false;
                }else{
                    JSON.parse(text);
                    return true;                            
                }
            }
            catch (error){
                return false;
            }
        }

  //content of your real function   
        if(testJSON(text)){
            console.log("json");
        }else{
            console.log("not json");
        }
    }

//use it as a normal function
        myfunction('{"name":"kasun","age":10}')
0
Aylian Craspa