Как проверить, является ли строка допустимой строкой JSON в JavaScript без использования Try / Catch - PullRequest
449 голосов
/ 14 сентября 2010

Что-то вроде:

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

//should be true
IsJsonString(jsonString);

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

Решение не должно содержать try / catch.Некоторые из нас включают «разбить все ошибки», и им не нравится, когда отладчик ломает эти недопустимые строки JSON.

Ответы [ 18 ]

747 голосов
/ 14 сентября 2010

Используйте синтаксический анализатор JSON, например JSON.parse:

function IsJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
407 голосов
/ 05 декабря 2013

Я знаю, что я опоздал на этот вопрос на 3 года, но я чувствовал, что хочу вмешаться.

Хотя решение Gumbo работает отлично, оно не обрабатывает несколько случаев, когда нетВозникает исключение для JSON.parse({something that isn't JSON})

Я также предпочитаю возвращать проанализированный JSON одновременно, поэтому вызывающему коду не нужно вызывать JSON.parse(jsonString) во второй раз.

Этокажется, хорошо работает для моих нужд:

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;
};
146 голосов
/ 14 сентября 2010

Сначала комментарий. Вопрос был о том, чтобы не использовать try/catch.
Если вы не против использовать его, прочитайте ответ ниже. Здесь мы просто проверяем строку JSON с помощью регулярного выражения, и она будет работать в большинстве случаев, а не во всех.

Посмотрите вокруг строки 450 в https://github.com/douglascrockford/JSON-js/blob/master/json2.js

Существует регулярное выражение, проверяющее действительный JSON, что-то вроде:

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

}

РЕДАКТИРОВАТЬ : новая версия json2.js делает более сложный синтаксический анализ, чем выше, но все еще основанный на замене регулярного выражения (из комментария @ Mrchief )

47 голосов
/ 28 августа 2015
// vanillaJS
function isJSON(str) {
    try {
        return (JSON.parse(str) && !!str);
    } catch (e) {
        return false;
    }
}

Использование: isJSON({}) будет false, isJSON('{}') будет true.

Чтобы проверить, является ли что-то Array или Object ( проанализировано 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;

Использование: isAO({}) будет true, isAO('{}') будет false.

18 голосов
/ 07 августа 2015

Я использовал очень простой метод, чтобы проверить строку, является ли она действительным JSON или нет.

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

Результат с допустимой строкой JSON:

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

Результат с простой строкой;

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

Результат с объектом:

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

Результат с нулевым вводом:

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

Последний возвращает false, потому что типом нулевых переменных является object.

Это работает каждый раз. :)

11 голосов
/ 14 сентября 2010

в прототипе js у нас есть метод isJSON. попробуйте это

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

даже http://www.prototypejs.org/learn/json

"something".isJSON();
// -> false
"\"something\"".isJSON();
// -> true
"{ foo: 42 }".isJSON();
// -> false
"{ \"foo\": 42 }".isJSON();
10 голосов
/ 11 июля 2018

Вот мой рабочий код:

function IsJsonString(str) {
  try {
    var json = JSON.parse(str);
    return (typeof json === 'object');
  } catch (e) {
    return false;
  }
}
4 голосов
/ 07 ноября 2016

Из структуры прототипа String.isJSON определение здесь

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

, поэтому эту версию можно использовать для передачи строкового объекта

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 }" ) )
3 голосов
/ 08 декабря 2014

Этот ответ поможет снизить стоимость оператора trycatch.

Я использовал JQuery для разбора строк JSON и использовал оператор trycatch для обработки исключений, но создание исключений для непарсируемых строк замедлило мой код, поэтому я использовал простой Regex, чтобы проверить строку, если это возможная строка JSON или нет не останавливаясь, проверив его синтаксис, затем я использовал обычный способ, анализируя строку с помощью JQuery:

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

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

}

Я обернул предыдущий код в рекурсивную функцию для анализа вложенных ответов JSON.

2 голосов
/ 07 марта 2018
if(resp) {
    try {
        resp = $.parseJSON(resp);
        console.log(resp);
    } catch(e) {
        alert(e);
    }
}

надеюсь, что это работает и для вас

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...