J'ai un simple appel AJAX et le serveur renvoie soit une chaîne JSON avec des données utiles, soit une chaîne de message d'erreur générée par la fonction PHP mysql_error()
. Comment puis-je tester si ces données sont une chaîne JSON ou le message d'erreur.
Ce serait bien d'utiliser une fonction appelée isJSON
comme vous pouvez utiliser la fonction instanceof
pour tester si quelque chose est un tableau.
C'est ce que je veux:
if (isJSON(data)){
//do some data stuff
}else{
//report the error
alert(data);
}
Utilisez JSON.parse
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
Ce code est JSON.parse(1234)
ou JSON.parse(0)
ou JSON.parse(false)
ou JSON.parse(null)
tous renverront true.
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
J'ai donc réécrit le code de cette façon:
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;
}
Résultat du test:
Si le serveur répond avec JSON, il aura un type de contenu application/json
, s'il répond avec un message en texte brut, il doit alors avoir un type de contenu text/plain
. Assurez-vous que le serveur répond avec le type de contenu correct et testez-le.
lorsque vous utilisez jQuery $.ajax()
, la réponse aura la propriété responseJSON
si la réponse était JSON, vous pouvez le vérifier comme suit:
if (xhr.hasOwnProperty('responseJSON')) {}
J'aime la meilleure réponse, mais si c'est une chaîne vide, elle retourne true. Alors voici un correctif:
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;
}
Eh bien ... Cela dépend de la manière dont vous recevez vos données. Je pense que le serveur répond avec une chaîne Formatée JSON (à l'aide de json_encode () en PHP, par exemple). Si vous utilisez la publication JQuery et définissez les données de réponse sur un format JSON et que ce soit un JSON mal formé, cela produira une erreur:
$.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!"); }
});
Toutefois, si vous utilisez la réponse de type sous forme de texte, vous devez utiliser $ .parseJSON. Selon le site jQuery: "Le passage d'une chaîne JSON mal formée peut entraîner la génération d'une exception". Ainsi, votre code sera:
$.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',
});
Il existe probablement des tests que vous pouvez faire. Par exemple, si vous savez que le code JSON renvoyé sera toujours entouré de {
et de }
, vous pouvez tester ces caractères ou une autre méthode de hacky. Ou vous pouvez utiliser la bibliothèque json.org JS pour essayer de l'analyser et de vérifier si elle réussit.
Je suggérerais cependant une approche différente. Votre script PHP renvoie actuellement JSON si l'appel aboutit, mais quelque chose d'autre si ce n'est pas le cas. Pourquoi ne pas toujours renvoyer JSON?
Par exemple.
Appel réussi:
{ "status": "success", "data": [ <your data here> ] }
Appel erroné:
{ "status": "error", "error": "Database not found" }
Cela faciliterait beaucoup l'écriture de votre côté client JS - tout ce que vous avez à faire est de vérifier le membre "statut" et l'acte en conséquence.
var parsedData;
try {
parsedData = JSON.parse(data)
} catch (e) {
// is not a valid JSON string
}
Cependant, je vous suggérerai que votre appel/service http devrait toujours renvoyer des données au même format. Donc, si vous avez une erreur, vous devriez avoir un objet JSON qui enveloppe cette erreur:
{"error" : { "code" : 123, "message" : "Foo not supported" } }
Et peut-être utiliser comme code HTTP un code 5xx.
J'utilise seulement 2 lignes pour effectuer cela:
var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }
C'est tout!
Mais gardez à l'esprit qu'il y a 2 pièges:
1. JSON.parse(null)
renvoie null
2. Tout nombre ou chaîne peut être analysé avec la méthode JSON.parse()
.JSON.parse("5")
renvoie 5
JSON.parse(5)
renvoie 5
Jouons sur le code:
// 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
Vous pouvez essayer de le décoder et d’attraper l’exception exception (native ou json2.js ):
try {
newObj = JSON.parse(myJsonString);
} catch (e) {
console.log('Not JSON');
}
Cependant, je suggérerais de toujours rendre la réponse valide en JSON. Si votre requête MySQL vous renvoie une erreur, il vous suffit de renvoyer JSON avec l’erreur suivante:
{"error":"The MySQL error string."}
Et alors:
if (myParsedJSON.error) {
console.log('An error occurred: ' + myParsedJSON.error);
}
Toutes les chaînes json commencent par '{' ou '[' et se terminent par le '}' ou ']' correspondant, alors vérifiez-le.
Voici comment Angular.js le fait:
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
Je suggère en mode TypeScript:
export function stringify(data: any): string {
try {
return JSON.stringify(data)
} catch (e) {
return 'NOT_STRINGIFIABLE!'
}
}