javascript - valid - verify string is json




Como verificar se uma string é uma string JSON válida em JavaScript sem usar Try/Catch (12)

Esta resposta para reduzir o custo da declaração trycatch.

Eu usei o JQuery para analisar strings JSON e usei a instrução trycatch para lidar com exceções, mas lançar exceções para strings não analisáveis ​​desacelerou meu código, então usei o Regex simples para verificar a string se ela é uma string JSON possível ou não sem passar verificando sua sintaxe, então eu usei o modo normal analisando a string usando JQuery:

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

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

}

Eu agrupei o código anterior em uma função recursiva para analisar respostas JSON aninhadas.

Algo como:

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

//should be true
IsJsonString(jsonString);

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

A solução não deve conter try / catch. Alguns de nós ativam "interromper todos os erros" e não gostam que o depurador quebre essas cadeias JSON inválidas.


Aqui está a versão typescript também:

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;
};

Do framework de protótipo String.isJSON definição here

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

então esta é a versão que pode ser usada passando um objeto de 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, \"[email protected]\" : \"val\"}" ) )

console.log("this is not a json", isJSON( "{ \"key\" : 1, \"[email protected]\" : pippo }" ) )


Eu acho que sei porque você quer evitar isso. Mas talvez tente & catch! == try & catch. o) Isso veio em minha mente:

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

Então você também pode clip sujo para o objeto JSON, como:

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

Como isso encapsulado quanto possível, ele não pode quebrar em erro.


Inferi no comentário de abertura que o caso de uso está delineando se uma resposta é HTML ou JSON. Nesse caso, quando você recebe JSON, provavelmente deve analisá-lo e manipular JSON inválido em algum momento do seu código. Além de qualquer coisa, imagino que você gostaria de ser informado pelo seu navegador, caso o JSON seja esperado, mas o JSON inválido foi recebido (assim como os usuários por proxy de alguma mensagem de erro significativa)!

Fazer um regex completo para JSON é, portanto, desnecessário (como seria - na minha experiência - para a maioria dos casos de uso). Você provavelmente estaria melhor usando algo como o abaixo:

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
  }
}

Isso deve evitar que você tenha que lidar com código não-JSON válido e cuidar de duff json ao mesmo tempo.


Talvez seja útil:

    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));

saída:

IE7: string , objeto, string, string

CHROME: objeto, objeto, string, string


Você pode usar a função javascript eval() para verificar se é válida.

por exemplo

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
}

Alternativamente, você pode usar a função https://github.com/douglascrockford/JSON-js/blob/master/json2.js do https://github.com/douglascrockford/JSON-js/blob/master/json2.js :

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

if (json) {
  //this is json
}

Espero que isto ajude.

ATENÇÃO : eval() é perigoso se alguém adicionar código JS malicioso, já que ele será executado. Certifique-se de que o JSON String seja confiável , ou seja, você o obteve de uma fonte confiável.

Editar Para a minha primeira solução, é recomendável fazer isso.

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

Para garantir json-ness. Se o jsonString não for puro JSON, o eval lançará uma exceção.



Um comentário primeiro. A questão era sobre não usar try/catch .
Se você não se importa em usá-lo, leia a resposta abaixo. Aqui, apenas verificamos uma string JSON usando um regexp e ela funcionará na maioria dos casos, não em todos os casos.

Dê uma olhada na linha 450 em https://github.com/douglascrockford/JSON-js/blob/master/json2.js

Há um regexp que verifica um JSON válido, algo como:

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 : A nova versão do json2.js faz uma análise mais avançada do que acima, mas ainda com base em uma substituição de expressão regular (do comentário de @Mrchief )


Ah, você pode definitivamente usar try catch para verificar se é um JSON válido ou não

Testado no Firfox Quantom 60.0.1

use a função dentro de uma função para obter o JSON testado e use essa saída para validar a string. ouve um exemplo.

    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}')

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

Uso: isJSON({}) será false , isJSON('{}') será true .

Para verificar se algo é uma Array ou Object (JSON analisado ):

// 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;

Uso: isAO({}) será true , isAO('{}') será false .


function get_json(txt)
{  var data

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

   return data;
}

Se houver erros, retorne false.

Se não houver erros, retorne os dados do json





json