AJAX: проверить, является ли строка JSON?


83

Мой JavaScript иногда дает сбой в этой строке:

var json = eval('(' + this.responseText + ')');

Сбои возникают, когда аргумент eval()не является JSON. Есть ли способ проверить, является ли строка JSON перед выполнением этого вызова?

Я не хочу использовать фреймворк - есть ли способ заставить эту работу работать, используя только eval()? (Обещаю, на это есть веская причина.)


Вы можете попытаться выполнить JSON.parse () в try / catch ... если вам удастся поймать, это недействительная разметка JSON. Конечно, это вроде как неэффективно, хех ... Не могли бы вы привести мне пример неверной разметки JSON, которую вы получаете?
— Warty

Ответы:


158

Если вы включите парсер JSON с json.org, вы можете использовать его функцию parse () и просто обернуть ее в try / catch, например:

try
{
   var json = JSON.parse(this.responseText);
}
catch(e)
{
   alert('invalid json');
}

Что-то подобное, вероятно, сделает то, что вы хотите.


9
используя jQuery.parseJSON (..), вам не нужно включать
— json.org

1
@Raymo OP не упомянул об использовании jQuery и json2.js размером менее половины jQuery (с точки зрения размера файла).
— brettkelly

Анализ всей строки - плохая практика, а выброс исключения может вызвать задержку
— благоухающий

он не вызовет исключения, если вы отправите
— числовую

21

Ее альтернатива jQuery ...

try
{
  var jsonObject = jQuery.parseJSON(yourJsonString);
}
catch(e)
{
  // handle error 
}

16

Я настоятельно рекомендую вам использовать библиотеку javascript JSON для сериализации в JSON и обратно. eval()представляет собой угрозу безопасности, которую никогда не следует использовать, если вы не уверены, что входные данные дезинфицированы и безопасны.

Имея библиотеку JSON, просто оберните вызов в его parse()эквивалент в блоке try / catch для обработки ввода, отличного от JSON:

try
{
  var jsonObject = JSON.parse(yourJsonString);
}
catch(e)
{
  // handle error 
}

2

Возможно, это поможет: с помощью этого кода вы можете напрямую получать свои данные ...

<!DOCTYPE html>
<html>
<body>

<h3>Open console, please, to view result!</h3>
<p id="demo"></p>

<script>
var tryJSON = function (test) {
	try {
	    JSON.parse(test);
	}
	catch(err) {
    	// maybe you need to escape this… (or not)
	    test = '"'+test.replace(/\\?"/g,'\\"')+'"';
	}
	eval('test = '+test);
	console.debug('Try json:', test);
};

// test with string…
var test = 'bonjour "mister"';
tryJSON(test);
// test with JSON…
var test = '{"fr-FR": "<p>Ceci est un texte en français !</p>","en-GB": "<p>And here, a text in english!</p>","nl-NL": "","es-ES": ""}';
tryJSON(test);
</script>

</body>
</html>


Существует множество альтернативных способов достижения того же результата, использование eval (), вероятно, является наименее подходящим.
— Дэвид

1

Проблема с зависимостью от try-catchподхода заключается в том, что JSON.parse('123') = 123он не вызывает исключения. Следовательно, помимо типа try-catch, нам нужно проверить тип следующим образом:

function isJsonStr(str) {
    var parsedStr = str;
    try {
        parsedStr = JSON.parse(str);
    } catch (e) {
        return false;
    }
    return typeof parsedStr == 'object'
}

0

Почему нельзя просто проверить, какой ответ? Это более эффективно.

var result;

if (response.headers['Content-Type'] === 'application/json')
    result = JSON.parse(this.responseText);
else
    result = this.responseText;

экран1


-1

Есть крошечная библиотека, которая проверяет типы JavaScript: is.js

is.json({foo: 'bar'});
=> true

// functions are returning as false
is.json(toString);
=> false

is.not.json([]);
=> true

is.all.json({}, 1);
=> false

is.any.json({}, 2);
=> true

// 'all' and 'any' interfaces can also take array parameter
is.all.json([{}, {foo: 'bar'}]);
=> true

На самом деле is.js - это нечто большее, некоторые достойные упоминания:

var obj = document.createElement('div');
is.domNode(obj);
=> true

is.error(new Error());
=> true

is.function(toString);
=> true

is.chrome();
=> true if current browser is chrome


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.