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

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

Brettkelly
источник
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 
}
RayLoveless
источник
16

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

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

try
{
  var jsonObject = JSON.parse(yourJsonString);
}
catch(e)
{
  // handle error 
}
Håvard S
источник
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


Рамазан Полат
источник