javascript - saber - ¿Cómo probar si una cadena es JSON o no?
cómo saber cuándo una cadena es de oro (14)
Además de las respuestas anteriores, en caso de que necesite validar un formato JSON como "{}", puede usar el siguiente código:
const validateJSON = (str) => {
try {
const json = JSON.parse(str);
if (Object.prototype.toString.call(json).slice(8,-1) !== ''Object'') {
return false;
}
} catch (e) {
return false;
}
return true;
}
Ejemplos de uso:
validateJSON(''{}'')
true
validateJSON(''[]'')
false
validateJSON('''')
false
validateJSON(''2134'')
false
validateJSON(''{ "Id": 1, "Name": "Coke" }'')
true
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
misma manera que se puede 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);
}
Bueno ... Depende de la forma en que recibas tus datos. Creo que el servidor está respondiendo con una cadena formateada JSON (usando json_encode () en PHP, por ejemplo). Si está utilizando una publicación de JQuery y configura los datos de respuesta para que sean un formato JSON y se trata de un JSON malformado, se producirá un error:
$.ajax({
type: ''POST'',
url: ''test2.php'',
data: "data",
success: function (response){
//Supposing x is a JSON property...
alert(response.x);
},
dataType: ''json'',
//Invalid JSON
error: function (){ alert("error!"); }
});
Pero, si usa la respuesta tipo como texto, necesita usar $ .parseJSON. Según el sitio de jquery: "Al pasar una cadena JSON malformada se puede generar una excepción". Por lo tanto, su código será:
$.ajax({
type: ''POST'',
url: ''test2.php'',
data: "data",
success: function (response){
try {
parsedData = JSON.parse(response);
} catch (e) {
// is not a valid JSON string
}
},
dataType: ''text'',
});
Este código es JSON.parse(1234)
o JSON.parse(0)
o JSON.parse(false)
o JSON.parse(null)
todos devolverán verdadero.
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
Así que reescribí el código de esta manera:
function isJson(item) {
item = typeof item !== "string"
? JSON.stringify(item)
: item;
try {
item = JSON.parse(item);
} catch (e) {
return false;
}
if (typeof item === "object" && item !== null) {
return true;
}
return false;
}
Resultado de la prueba:
Me gusta la mejor respuesta, pero si se trata de una cadena vacía, devuelve verdadero. Así que aquí hay una solución:
function isJSON(MyTestStr){
try {
var MyJSON = JSON.stringify(MyTestStr);
var json = JSON.parse(MyJSON);
if(typeof(MyTestStr) == ''string'')
if(MyTestStr.length == 0)
return false;
}
catch(e){
return false;
}
return true;
}
Para construir sobre la primera respuesta, en lugar de copiar y pegar el código, puede importar este json-validador de código abierto para validar una cadena json.
Aquí hay un ejemplo de uso:
const vaildateJson = require(''bit/global/json-validator'');
vaildateJson(jsonStr).catch(err => console.log(err))
Probablemente haya pruebas que pueda hacer, por ejemplo, si sabe que el JSON devuelto siempre estará rodeado por {
y }
entonces podría probar esos caracteres, o algún otro método hacky. O puede usar la biblioteca JS de json.org para intentar analizarla y probar si tiene éxito.
Sin embargo, sugeriría un enfoque diferente. Su script PHP actualmente devuelve JSON si la llamada fue exitosa, pero algo más si no lo es. ¿Por qué no siempre devuelves JSON?
P.ej
Llamada exitosa:
{ "status": "success", "data": [ <your data here> ] }
Llamada errónea:
{ "status": "error", "error": "Database not found" }
Esto haría que escribir su JS del lado del cliente sea mucho más fácil: todo lo que tiene que hacer es verificar el miembro de "estado" y el acto en consecuencia.
Puede tratar de decodificarlo y capturar la exception (native o json2.js ):
try {
newObj = JSON.parse(myJsonString);
} catch (e) {
console.log(''Not JSON'');
}
Sin embargo, sugeriría que la respuesta siempre sea válida JSON. Si obtiene un error de su consulta MySQL, simplemente envíe de vuelta JSON con el error:
{"error":"The MySQL error string."}
Y entonces:
if (myParsedJSON.error) {
console.log(''An error occurred: '' + myParsedJSON.error);
}
Si el servidor está respondiendo con JSON, entonces tendría un tipo de contenido application/json
, si está respondiendo con un mensaje de texto sin formato, entonces debería tener un text/plain
tipo de contenido text/plain
. Asegúrese de que el servidor responda con el tipo de contenido correcto y pruébelo.
Sugiero en modo de mecanografía:
export function stringify(data: any): string {
try {
return JSON.stringify(data)
} catch (e) {
return ''NOT_STRINGIFIABLE!''
}
}
Todas las cadenas json comienzan con ''{'' o ''['' y terminan con el ''}'' o '']'' correspondiente, así que simplemente verifique eso.
Así es como lo hace Angular.js:
var JSON_START = /^/[|^/{(?!/{)/;
var JSON_ENDS = {
''['': /]$/,
''{'': /}$/
};
function isJsonLike(str) {
var jsonStart = str.match(JSON_START);
return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
}
https://github.com/angular/angular.js/blob/v1.6.x/src/ng/http.js
Use JSON.parse
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
Uso solo 2 líneas para realizar eso:
var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }
¡Eso es todo!
Pero ten en cuenta que hay 2 trampas:
1. JSON.parse(null)
devuelve null
2. Cualquier número o cadena se puede analizar con el método JSON.parse()
.
JSON.parse("5")
devuelve 5
JSON.parse(5)
devuelve 5
Vamos a jugar un poco al código:
// TEST 1
var data = ''{ "a": 1 }''
// Avoiding ''null'' trap! Null is confirmed as JSON.
var isValidJSON = data ? true : false
try { JSON.parse(data) } catch(e) { isValidJSON = false }
console.log("data isValidJSON: ", isValidJSON);
console.log("data isJSONArray: ", isValidJSON && JSON.parse(data).length ? true : false);
Console outputs:
data isValidJSON: true
data isJSONArray: false
// TEST 2
var data2 = ''[{ "b": 2 }]''
var isValidJSON = data ? true : false
try { JSON.parse(data2) } catch(e) { isValidJSON = false }
console.log("data2 isValidJSON: ", isValidJSON);
console.log("data2 isJSONArray: ", isValidJSON && JSON.parse(data2).length ? true : false);
Console outputs:
data2 isValidJSON: true
data2 isJSONArray: true
// TEST 3
var data3 = ''[{ 2 }]''
var isValidJSON = data ? true : false
try { JSON.parse(data3) } catch(e) { isValidJSON = false }
console.log("data3 isValidJSON: ", isValidJSON);
console.log("data3 isJSONArray: ", isValidJSON && JSON.parse(data3).length ? true : false);
Console outputs:
data3 isValidJSON: false
data3 isJSONArray: false
// TEST 4
var data4 = ''2''
var isValidJSON = data ? true : false
try { JSON.parse(data4) } catch(e) { isValidJSON = false }
console.log("data4 isValidJSON: ", isValidJSON);
console.log("data4 isJSONArray: ", isValidJSON && JSON.parse(data4).length ? true : false);
Console outputs:
data4 isValidJSON: true
data4 isJSONArray: false
// TEST 5
var data5 = ''''
var isValidJSON = data ? true : false
try { JSON.parse(data5) } catch(e) { isValidJSON = false }
console.log("data5 isValidJSON: ", isValidJSON);
console.log("data5 isJSONArray: ", isValidJSON && JSON.parse(data5).length ? true : false);
Console outputs:
data5 isValidJSON: false
data5 isJSONArray: false
// TEST 6
var data6; // undefined
var isValidJSON = data ? true : false
try { JSON.parse(data6) } catch(e) { isValidJSON = false }
console.log("data6 isValidJSON: ", isValidJSON);
console.log("data6 isJSONArray: ", isValidJSON && JSON.parse(data6).length ? true : false);
Console outputs:
data6 isValidJSON: false
data6 isJSONArray: false
cuando se usa jQuery $.ajax()
la respuesta tendrá la propiedad responseJSON
si la respuesta fue JSON, esto podría verificarse así:
if (xhr.hasOwnProperty(''responseJSON'')) {}
var parsedData;
try {
parsedData = JSON.parse(data)
} catch (e) {
// is not a valid JSON string
}
Sin embargo, le sugiero que su llamada / servicio http debería devolver siempre una información en el mismo formato. Entonces, si tiene un error, entonces debería tener un objeto JSON que ajuste este error:
{"error" : { "code" : 123, "message" : "Foo not supported" } }
Y tal vez use tan bien como el estado HTTP un código 5xx.