AJAX: Перевірте, чи рядок є JSON?


83

Мій JavaScript іноді аварійно завершує роботу в цьому рядку:

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

Збої виникають, коли аргумент eval()не є JSON. Чи є спосіб перевірити, чи є рядок JSON перед здійсненням цього виклику?

Я не хочу використовувати фреймворк - чи є спосіб зробити цю роботу просто eval()? (Є поважна причина, я обіцяю.)


Ви можете спробувати JSON.parse () у спробі / лові ... якщо ви потрапите на catch, це недійсна розмітка JSON. Звичайно, це начебто неефективно, хе ... Чи не могли б ви дати мені приклад недійсної розмітки JSON, яку ви отримуєте?
Warty

Відповіді:


157

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

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

Щось подібне, мабуть, зробить те, що ти хочеш.


9
використовуючи jQuery.parseJSON (..) вам не потрібно буде включати json.org
RayLoveless

1
@Raymo OP не згадував про використання jQuery та json2.js менше половини розміру jQuery (з точки зору розміру файлу).
brettkelly

Синтаксичний розбір цілого рядка є поганою практикою, і додавання винятку може призвести до відставання
повторно

це не буде винятком, якщо ви надішлете
числовий

21

Її альтернатива jQuery ...

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

15

Я настійно рекомендую вам використовувати бібліотеку JSON javascript для серіалізації до та з 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 (), мабуть, є найменш підходящим.
Девід

0

Проблема залежно від 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.