jQuery ne va pas analyser mon JSON de la requête AJAX

j'ai de la difficulté à analyser certaines données JSON retournées depuis mon serveur en utilisant jQuery.ajax()

pour effectuer L'AJAX que j'utilise:

$.ajax({
  url: myUrl,
  cache: false,
  dataType: "json",
  success: function(data){
    ...
  },
  error: function(e, xhr){
    ...
  }
});  

et si je rends un tableau d'articles alors il fonctionne très bien:

[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]

la fonction de succès est appelée et reçoit l'objet correct.

cependant, quand j'essaie de rendre un seul objet:

{ title: "One", key: "1" } 

l'erreur la fonction est appelée et xhr contient "parsererror'. J'ai essayé d'enrouler le JSON entre parenthèses sur le serveur avant de l'envoyer sur le fil, mais ça ne fait aucune différence. Pourtant, si je colle le contenu dans une chaîne de caractères en Javascript et que j'utilise ensuite la fonction eval (), elle l'évalue parfaitement.

une idée de ce que je fais de mal?

Anthony

87
demandé sur littlecharva 2008-10-30 12:47:17

20 réponses

votre serveur envoie-t-il des données en tant que Contenu de type "*/json" ? Dans la négative, modifiez les en-têtes de réponse en conséquence. Envoyer "application/json" serait très bien, par exemple.

71
répondu Tomalak 2008-10-30 10:29:13

selon le json.org spécification, votre déclaration n'est pas valide. Les noms sont toujours cités, donc vous devriez retourner

{ "title": "One", "key": "1" }

et

[ { "title": "One", "key": "1" }, { "title": "Two", "key": "2" } ]

ce n'est peut-être pas le problème avec votre configuration, puisque vous dites que l'un d'eux fonctionne maintenant, mais il doit être corrigé pour être correct au cas où vous devez passer à un autre analyseur JSON dans le futur.

51
répondu Ben Combee 2008-10-30 17:45:49
Les cordes

JSON sont enveloppées dans des guillemets double ; les guillemets simples ne sont pas un substitut valide.

{"who": "Hello World"}

est valide, mais ce n'est pas le cas...

{'who': 'Hello World'}

bien que ce ne soit pas la question de L'OP, j'ai pensé qu'il valait la peine de noter pour les autres qui atterrissent ici.

33
répondu John Mee 2010-03-25 22:45:12

ce problème est généralement dû au fait que votre requête a reçu le mauvais type de mime. Lorsque vous développez sur votre propre ordinateur, parfois vous ne recevez pas le type mime approprié du "serveur", qui est votre propre ordinateur. J'ai rencontré ce problème une fois lors du développement en ouvrant le fichier localement stocké dans le navigateur (par exemple, l'url était "c:/project/test.HTML.)"

essayez d'utiliser la propriété beforeSend pour ajouter une fonction de rappel qui remplace le type mime. Ce sera astuce le code à traiter avec json malgré le mauvais type mime envoyé par le serveur et reçus par votre code d'appel. Un exemple de code est ci-dessous.

le type mime approprié est application/json selon cette question , mais je sais que application/j-son a fonctionné quand je l'ai essayé (maintenant il ya plusieurs années). Vous devriez probablement essayer application / json d'abord.

var jsonMimeType = "application/json;charset=UTF-8";
$.ajax({
 type: "GET",
 url: myURL,
 beforeSend: function(x) {
  if(x && x.overrideMimeType) {
   x.overrideMimeType(jsonMimeType);
  }
 },
 dataType: "json",
 success: function(data){
  // do stuff...
 }
});
30
répondu Josh 2017-05-23 11:47:19

j'ai eu ce problème et pour un peu, j'ai utilisé

eval('('+data+')')

pour obtenir les données renvoyées dans un objet. mais plus tard, d'autres problèmes sont apparus avec l'erreur de parenthetical et ont découvert que jQuery avait une fonction spécifique pour évaluer une chaîne de caractères pour une structure json:

$.parseJSON(data)

devrait faire l'affaire. C'est en plus d'avoir votre chaîne json dans le format correct de cours..

7
répondu Jubair 2010-12-16 22:00:55

si vous faites écho à la réponse de json et que vos en-têtes ne correspondent pas à */json, vous pouvez utiliser le construit en jQuery.parsejson api pour analyser la réponse.

response = '{"name":"John"}';
var obj = jQuery.parseJSON(response);
alert( obj.name === "John" );
6
répondu Nezzy 2012-05-16 22:44:00
{ title: "One", key: "1" }

n'est pas ce que vous pensez. En tant qu'expression, c'est un objet littéral, mais en tant que Déclaration, c'est:

{                // new block
    title:       // define a label called 'title' for goto statements
        "One",   // statement: the start of an expression which will be ignored
        key:     // ...er, what? you can't have a goto label in the middle of an expression
                 // ERROR

malheureusement eval () ne vous donne pas un moyen de spécifier si vous lui donnez une déclaration ou une expression, et il a tendance à deviner faux.

La solution habituelle est en effet d'envelopper rien entre parenthèses avant de l'envoyer à la fonction eval (). Vous dites que vous avez essayé que sur le serveur... clairement d'une certaine manière qui n'est pas de passer à travers. Il doit être étanche pour dire sur le côté du client, quoi que reçoit la réponse XMLHttpRequest:

eval('('+responseText+')');

au lieu de:

eval(responseText);

aussi longtemps que la réponse est vraiment une expression et non une affirmation. (eg. il n'y a pas de clauses multiples, séparées par un point-virgule ou une nouvelle ligne.)

4
répondu bobince 2010-01-13 12:42:39

si vous consommez ASP.NET Services Web en utilisant jQuery, assurez-vous que vous avez ce qui suit inclus dans votre web.config:

<webServices>
    <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
    </protocols>
</webServices>
2
répondu Andreas Grech 2008-12-08 21:05:25

j'ai eu un problème similaire à ce où Firefox 3.5 travaillé très bien et analysé mes données JSON, mais Firefox 3.0.6 retourné une parseerror. Il s'est avéré que C'était un espace vide au début du JSON qui a fait Firefox 3.0.6 jeter une erreur. Suppression de l'espace vide fixé it

2
répondu jonburney 2010-01-27 11:52:03

vous devrez définir le type de contenu de l'en-tête dans votre php comme ceci:

 <?php

 header('Content-type:application/json');

 ?>

Regardez cette vidéo pour une meilleure compréhension....

référence: http://www.youtube.com/watch?v=EvFXWqEqh6o

2
répondu user3612872 2014-07-27 04:59:34

Les techniques "eval()" et "JSON.parse () " utiliser des formats mutuellement exclusifs.

  • Avec "eval()" entre parenthèses sont nécessaire .
  • avec " JSON.parse()" entre parenthèses sont interdit .

attention, il y a des fonctions" stringify () "qui produisent le format" eval". Pour ajax, vous devez utiliser seulement le format JSON.

Alors que "eval" incorpore tout le langage JavaScript, JSON utilise seulement un petit sous-ensemble du langage. Parmi les constructions dans le langage JavaScript que "eval" doit reconnaître est le "Block statement" (A. K. A. "compound statement") ; qui est une paire ou des bagues bouclées "{} " avec quelques déclarations à l'intérieur. Mais les accolades sont aussi utilisées dans la syntaxe des littérales d'objets. L'interprétation est différenciée par le contexte dans lequel le code s'affiche. Quelque chose pourrait sembler comme un objet littéral pour vous, mais "eval" le verra comme un énoncé composé.

dans le langage JavaScript, les littérales d'objet se produisent à la droite d'une tâche.

var myObj = { ...some..code..here... };

les objets littéraux ne se produisent pas seuls.

{ ...some..code..here... }   // this looks like a compound statement

revenant à la question initiale de L'OP, posée en 2008, il s'est enquis des raisons pour lesquelles la réponse suivante échoue dans "eval ()":

{ title: "One", key: "1" }

La réponse est qu'il ressemble comme une instruction composée. Pour le transformer en objet, vous devez le mettre dans un contexte où une déclaration composée est impossible. Cela est fait en mettant la parenthèse autour de lui

( { title: "One", key: "1" } )    // not a compound statment, so must be object literal

L'OP a également demandé pourquoi une déclaration similaire a avec succès eval:

[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]

La même réponse s'applique -- les accolades sont dans un contexte où une instruction composée est impossible. C'est un contexte de tableau, " [...] ", et les tableaux peuvent contenir des objets, mais ils ne peuvent pas contenir de déclarations.

contrairement à " eval ()", JSON est très limité dans ses capacités. La limitation est intentionnelle. Le concepteur de JSON a prévu un sous-ensemble minimaliste de JavaScript, en utilisant seulement la syntaxe qui pourrait apparaître sur le côté droit d'une tâche. Donc si vous avez un code qui passe correctement dans JSON...

var myVar = JSON.parse("...some...code...here...");

...cela implique qu'il va également juridiquement Parser sur le côté droit d'une affectation, à l'instar de ce..

var myVar = ...some..code..here... ;

mais ce n'est pas la seule restriction sur JSON. Le BNF language specification for JSON est très simple. Par exemple, il ne permet pas l'utilisation de guillemets simples pour indiquer des chaînes (comme JavaScript et Perl do) et il n'a pas de façon d'exprimer un caractère simple comme un octet (comme " C " does). Malheureusement, il ne permet pas non plus de commentaires (ce qui serait vraiment bien quand création de fichiers de configuration). Le bon côté de toutes ces limites est que parsing JSON est rapide et n'offre aucune possibilité d'injection de code (une menace de sécurité).

à cause de ces limitations, JSON n'a pas besoin de parenthèses. Par conséquent, une parenthèse dans une chaîne JSON est un caractère illégal.

toujours utiliser le format JSON avec ajax, pour les raisons suivantes:

  • un pipeline ajax typique sera configuré pour JSON.
  • l'utilisation de" eval () " sera critiquée comme un risque pour la sécurité.

comme exemple d'un pipeline ajax, considérez un programme qui implique un serveur de noeuds et un client jQuery. Le programme client utilise un appel jQuery ayant le formulaire $.ajax({dataType:'json',...etc.}); . JQuery crée un objet jqXHR pour une utilisation ultérieure, puis empaquette et envoie la requête associée. Le serveur accepte la requête, la traite et est prêt à répondre. Le le programme de serveur appellera la méthode res.json(data) pour empaqueter et envoyer la réponse. De retour chez le client, jQuery accepte la réponse, consulte l'objet jqXHR associé et traite les données formatées par JSON. Tout cela fonctionne sans besoin de conversion manuelle des données. La réponse n'implique aucun appel explicite à JSON.stringify () sur le serveur de noeuds, et aucun appel explicite à JSON.parle () sur le client; tout est géré pour vous.

L'utilisation de "eval" est associé avec les risques de sécurité d'injection de code. Vous pourriez penser qu'il n'y a aucune chance que cela arrive, mais les pirates peuvent devenir très créatifs. En outre, "eval" est problématique pour l'optimisation Javascript.

si vous utilisez une fonction" stringify ()", sachez que certaines fonctions de ce nom créeront des chaînes compatibles avec" eval " et non avec JSON. Par exemple, dans le noeud, ce qui suit vous donne la fonction qui crée des chaînes dans le format compatible "eval" :

var stringify = require('node-stringify'); // generates eval() format

Cela peut être utile, mais à moins d'avoir un besoin spécifique, il n'est probablement pas ce que vous voulez.

2
répondu IAM_AL_X 2016-11-16 05:17:29

si retourner un tableau fonctionne et retourner un objet unique ne fonctionne pas, vous pouvez aussi essayer de retourner votre objet unique comme un tableau contenant cet objet unique:

[ { title: "One", key: "1" } ]

de cette façon, vous retournez une structure de données cohérente, un tableau d'objets, peu importe la charge utile de données.

je vois que vous avez essayé d'emballer votre objet unique dans" parenthèse", et suggérez ceci avec l'exemple parce que bien sûr JavaScript traite [ .. ] différemment des ( .. )

1
répondu David Alpert 2008-10-30 14:17:19

si le gestionnaire d'erreurs de jQuery est appelé et que L'objet XHR contient" parser error", il s'agit probablement d'une erreur de parser provenant du serveur.

est votre scénario de résultat multiple quand vous appelez le service sans paramètre, mais il casse quand vous essayez de fournir un paramètre pour récupérer l'enregistrement unique?

de quel support vous retournez ça?

sur les services ASMX, par exemple, c'est souvent le cas où les paramètres sont fournis à jQuery en tant qu'objet JSON au lieu d'une chaîne JSON. Si vous fournissez à jQuery un objet JSON réel pour son paramètre "data", il le sérialisera en paires standard & délimitées k, v au lieu de l'envoyer comme JSON.

1
répondu Dave Ward 2008-11-28 04:48:05

j'ai trouvé dans certaines de mes implémentations que j'ai dû ajouter:

obj = new Object; obj = (data.obj);

qui semblait résoudre le problème. Eval ou pas, il semblait faire exactement la même chose pour moi.

1
répondu Jay 2008-11-29 16:01:01

jQuery s'étouffe sur certaines clés JSON. J'envoyais cet extrait de JSON en PHP:

echo json_encode((object) array('result' => 'success'));

renommer la clé 'résultat' à quelque chose d'autre fonctionne. Je suppose qu'il s'agit d'une collision de mot réservé d'une sorte, et pourrait être un bug dans jQuery (1.4.2).

1
répondu Jonathon Hill 2011-01-07 23:34:30

dans un environnement ColdFusion, une chose qui causera une erreur, même avec JSON bien formé, est d'avoir activer la sortie de débogage de requête activée dans L'administrateur de ColdFusion (sous débogage & journalisation > paramètres de sortie de débogage). Les informations de débogage seront retournées avec les données JSON et seront donc invalides.

1
répondu Dave DuPlantis 2011-04-04 17:40:16

essayez aussi

$.ajax({
    url: url,
    data:datas,
    success:function(datas, textStatus, jqXHR){
    var returnedData = jQuery.parseJSON(datas.substr(datas.indexOf('{')));
})};

dans mon cas le serveur répond avec le caractère unknow avant ' {'

1
répondu valir 2012-04-06 13:22:56

j'obtenais le statut = parseerror et xhr.statut = 200.

le problème pour moi était L'URL à l'intérieur de la réponse JSON avait '\' commuting to '/' corrigé ceci.

1
répondu Brent 2014-04-23 14:20:15

je me débattais avec ça, et j'ai passé quelques heures à essayer de comprendre, jusqu'à ce que j'utilise firebug pour montrer l'objet de données.

var data = eval("(" + data.responseText + ")");
console.log(data.count);
0
répondu webwiseguys 2012-11-23 12:04:36

utiliser

$data = yourarray(); 
json_encode($data)

côté serveur. Sur le côté client utilisez ajax avec Datatype JSON et assurez-vous que votre document encoding n'est pas UTF-8 avec BOM il doit être UTF-8.

-1
répondu user2854865 2017-05-17 15:12:53