¿Cómo probar si una cadena es JSON o no?
Tengo una llamada AJAX simple y el servidor devolverá una cadena JSON con datos útiles o una cadena de mensaje de error producida por la función PHP mysql_error()
. ¿Cómo puedo probar si estos datos son una cadena JSON o el mensaje de error?
Sería bueno usar una función llamada isJSON
de la misma manera que puedes usar la función instanceof
para probar si algo es una matriz.
Esto es lo que quiero:
if (isJSON(data)){
//do some data stuff
}else{
//report the error
alert(data);
}
Utilice JSON.parse
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
Usar JSON.parse() tiene algunos inconvenientes:
JSON.parse(1234)
oJSON.parse(0)
oJSON.parse(false)
oJSON.parse(null)
todo volverá a ser cierto.
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
function testIsJson(value, expected) {
console.log(`Expected: ${expected}, Actual: ${isJson(value)}`);
}
// All of the following codes are expected to return false.
// But actually returns true.
testIsJson(1234, false);
testIsJson(0, false);
testIsJson(false, false);
testIsJson(null, false);
Código que maneja falsos positivos
Entonces reescribí el código de esta manera:
function isJson(item) {
let value = typeof item !== "string" ? JSON.stringify(item) : item;
try {
value = JSON.parse(value);
} catch (e) {
return false;
}
return typeof value === "object" && value !== null;
}
Resultado de la prueba:
function isJson(item) {
let value = typeof item !== "string" ? JSON.stringify(item) : item;
try {
value = JSON.parse(value);
} catch (e) {
return false;
}
return typeof value === "object" && value !== null;
}
function testIsJson(value, expected) {
console.log(`Expected: ${expected}, Actual: ${isJson(value)}`);
}
const validJson = { "foo": "bar" };
const notValidJson = '{ "foo": "bar" } invalid';
// expected: true
testIsJson(validJson, true);
// expected: false
testIsJson(1234, false);
testIsJson(0, false);
testIsJson(notValidJson, false);
testIsJson(false, false);
testIsJson(null, false);
Recapitulemos esto (para 2019+).
Argumento : Valores como
true
,, son JSONfalse
válidosnull
(?)
HECHO : Estos valores primitivos son analizables en JSON pero no son estructuras JSON bien formadas . La especificación JSON indica que JSON se basa en dos estructuras: una colección de pares de nombre/valor (objeto) o una lista ordenada de valores (matriz).
Argumento : el manejo de excepciones no debería usarse para hacer algo esperado.
(¡Este es un comentario que tiene más de 25 votos a favor!)
HECHO : ¡No! Definitivamente es legal usar try/catch, especialmente en un caso como este. De lo contrario, necesitaría hacer muchas cosas de análisis de cadenas, como operaciones de tokenización/regex; lo que tendría un rendimiento terrible.
hasJsonStructure()
Esto es útil si su objetivo es comprobar si algunos datos/texto tienen el formato de intercambio JSON adecuado.
function hasJsonStructure(str) {
if (typeof str !== 'string') return false;
try {
const result = JSON.parse(str);
const type = Object.prototype.toString.call(result);
return type === '[object Object]'
|| type === '[object Array]';
} catch (err) {
return false;
}
}
Uso:
hasJsonStructure('true') // —» false
hasJsonStructure('{"x":true}') // —» true
hasJsonStructure('[1, false, null]') // —» true
safeJsonParse()
Y esto es útil si desea tener cuidado al analizar algunos datos en un valor de JavaScript.
function safeJsonParse(str) {
try {
return [null, JSON.parse(str)];
} catch (err) {
return [err];
}
}
Uso:
const [err, result] = safeJsonParse('[Invalid JSON}');
if (err) {
console.log('Failed to parse JSON: ' + err.message);
} else {
console.log(result);
}