it-swarm.com.de

jQuery analysiert mein JSON nicht aus AJAX query

Ich habe Probleme beim Parsen einiger JSON-Daten, die mit jQuery.ajax () von meinem Server zurückgegeben wurden.

Um die AJAX auszuführen, benutze ich:

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

Und wenn ich eine Reihe von Gegenständen zurückgebe, funktioniert es einwandfrei:

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

Die Erfolgsfunktion wird aufgerufen und erhält das richtige Objekt.

Wenn ich jedoch versuche, ein einzelnes Objekt zurückzugeben:

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

Die Fehlerfunktion wird aufgerufen und xhr enthält 'Parsererror'. Ich habe versucht, den JSON-Code in Klammern auf den Server zu setzen, bevor ich ihn über die Leitung gesendet habe, aber es macht keinen Unterschied. Wenn ich den Inhalt jedoch in Javascript in einen String einfüge und dann die Funktion eval () verwende, wird er perfekt ausgewertet.

Irgendwelche Ideen, was ich falsch mache?

Anthony

87
littlecharva

Sendet Ihr Server Daten als Inhaltstyp "*/json"? Wenn nicht, ändern Sie die Antwortheader entsprechend. Senden von "application/json" wäre zum Beispiel in Ordnung.

71
Tomalak

Gemäß der json.org Spezifikation ist Ihre Rücksendung ungültig. Die Namen werden immer in Anführungszeichen gesetzt, Sie sollten also zurückkehren

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

und

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

Dies ist möglicherweise nicht das Problem bei Ihrem Setup, da Sie sagen, dass einer von ihnen jetzt funktioniert. Es sollte jedoch aus Gründen der Korrektheit behoben werden, falls Sie in Zukunft zu einem anderen JSON-Parser wechseln müssen.

51
Ben Combee

JSON-Zeichenfolgen werden in double Anführungszeichen eingeschlossen. einfache Anführungszeichen sind kein gültiger Ersatz.

{"who": "Hello World"}

ist gültig, aber das ist nicht ...

{'who': 'Hello World'}

Obwohl dies nicht das Problem des OP ist, ist es für andere, die hier landen, erwähnenswert.

33
John Mee

Dieses Problem ist normalerweise darauf zurückzuführen, dass Ihre Anfrage den falschen MIME-Typ erhalten hat. Wenn Sie auf Ihrem eigenen Computer entwickeln, erhalten Sie manchmal nicht den richtigen MIME-Typ vom "Server", der Ihr eigener Computer ist. Ich bin einmal beim Entwickeln auf dieses Problem gestoßen, indem ich die lokal gespeicherte Datei im Browser geöffnet habe (z. B. lautete die URL "c: /project/test.html").

Verwenden Sie die beforeSend -Eigenschaft, um eine Rückruffunktion hinzuzufügen, die den MIME-Typ überschreibt. Dadurch wird der Code dazu verleitet, mit JSON umzugehen, obwohl der falsche MIME-Typ vom Server gesendet und von Ihrem aufrufenden Code empfangen wird. Ein Beispielcode ist unten.

Der richtige MIME-Typ ist application/json gemäß diese Frage , aber ich weiß, dass application/j-son funktioniert hat, als ich es ausprobiert habe (jetzt vor einigen Jahren). Sie sollten wahrscheinlich zuerst application/json ausprobieren.

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
Josh

Ich hatte dieses Problem und für ein bisschen habe ich verwendet

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

um die Daten in einem Objekt zurückzugeben. Aber später hatten andere Probleme den Fehler, dass jQuery eine Funktion speziell zum Auswerten eines Strings für eine json-Struktur hat:

$.parseJSON(data)

sollte den Trick machen. Dazu gehört natürlich auch, dass Sie Ihren JSON-String im richtigen Format haben.

7
Jubair

Wenn Sie die json-Antwort als Echo ausgeben und Ihre Header nicht mit */json übereinstimmen, können Sie die Antwort mit der integrierten jQuery.parseJSON-API analysieren.

response = '{"name":"John"}';
var obj = jQuery.parseJSON(response);
alert( obj.name === "John" );
6
Nezzy
{ title: "One", key: "1" }

Ist nicht das, was du denkst. Als Ausdruck ist es ein Objektliteral, als Aussage jedoch:

{                // 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

Leider können Sie mit eval () nicht angeben, ob Sie eine Anweisung oder einen Ausdruck angeben, und es besteht die Tendenz, dass Sie falsch raten.

Die übliche Lösung besteht in der Tat darin, irgendetwas in Klammern zu setzen, bevor es an die eval () -Funktion gesendet wird. Sie sagen, Sie haben das auf dem Server versucht ... offensichtlich kommt das nicht durch. Es sollte wasserdicht sein, um auf Client-Seite zu sagen, was auch immer die XMLHttpRequest-Antwort empfängt:

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

anstatt:

eval(responseText);

solange die antwort wirklich ein ausdruck ist, keine aussage. (ZB hat es keine durch Semikolon oder Zeilenvorschub getrennten Mehrfachklauseln.)

4
bobince

Sie müssen den Header-Inhaltstyp in Ihrem PHP wie folgt einstellen:

 <?php

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

 ?>

Schau dir dieses Video zum besseren Verständnis an ....

Referenz: http://www.youtube.com/watch?v=EvFXWqEqh6o

3
user3612872

Ich hatte ein ähnliches Problem, bei dem Firefox 3.5 einwandfrei funktionierte und meine JSON-Daten analysierte, Firefox 3.0.6 jedoch einen Fehler zurückgab. Es stellte sich heraus, dass es sich beim Start von JSON um eine leere Stelle handelte, die dazu führte, dass Firefox 3.0.6 einen Fehler auslöste. Das Entfernen der Leerstelle behebt es

2
jonburney

Die Techniken "eval ()" und "JSON.parse ()" verwenden sich gegenseitig ausschließende Formate.

  • Bei "eval ()" sind Klammern erforderlich .
  • Bei "JSON.parse ()" sind Klammern verboten .

Achtung, es gibt "stringify ()" - Funktionen, die das "eval" -Format erzeugen. Für Ajax sollten Sie nur das JSON-Format verwenden.

Während "eval" die gesamte JavaScript-Sprache enthält, verwendet JSON nur einen kleinen Teil der Sprache. Zu den Konstrukten in der JavaScript-Sprache, die "eval" erkennen muss, gehört "Blockanweisung" (a.k.a. "zusammengesetzte Anweisung" ; Das ist ein Paar oder geschweifte Klammern "{}" mit einigen Anweisungen darin. Geschweifte Klammern werden aber auch in der Syntax von Objektliteralen verwendet. Die Interpretation unterscheidet sich durch den Kontext, in dem der Code erscheint. Etwas sieht für Sie vielleicht wie ein Objekt aus, aber "eval" sieht es als zusammengesetzte Aussage.

In der JavaScript-Sprache stehen Objektliterale rechts von einer Zuweisung.

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

Objektliterale treten nicht alleine auf.

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

Zurück zur ursprünglichen Frage des OP, die 2008 gestellt wurde, fragte er, warum das Folgende in "eval ()" fehlschlägt:

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

Die Antwort ist, dass es wie eine zusammengesetzte Aussage aussieht. Um es in ein Objekt zu konvertieren, müssen Sie es in einen Kontext stellen, in dem eine zusammengesetzte Anweisung unmöglich ist. Dies geschieht, indem Klammern gesetzt werden

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

Das OP fragte auch, warum eine ähnliche Aussage erfolgreich ausgewertet wurde :

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

Die gleiche Antwort gilt - die geschweiften Klammern stehen in einem Kontext, in dem eine zusammengesetzte Aussage unmöglich ist. Dies ist ein Array-Kontext "[...]", Und Arrays können Objekte enthalten, aber keine Anweisungen.

Im Gegensatz zu "eval ()" sind die Möglichkeiten von JSON sehr begrenzt. Die Einschränkung ist beabsichtigt. Der Designer von JSON beabsichtigte eine minimalistische Teilmenge von JavaScript, wobei nur die Syntax verwendet wurde, die auf der rechten Seite einer Zuweisung erscheinen konnte. Wenn Sie also Code haben, der in JSON korrekt analysiert wird ...

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

... das heißt, es wird auch legal auf der rechten Seite einer Aufgabe analysiert, so ..

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

Dies ist jedoch nicht die einzige Einschränkung für JSON. Die BNF-Sprachspezifikation für JSON ist sehr einfach. Beispielsweise ist die Verwendung von einfachen Anführungszeichen zur Angabe von Zeichenfolgen (wie bei JavaScript und Perl) nicht zulässig, und es gibt keine Möglichkeit, ein einzelnes Zeichen als Byte auszudrücken (wie bei 'C'). Leider erlaubt es auch keine Kommentare (was beim Erstellen von Konfigurationsdateien wirklich nett wäre). Die Kehrseite all dieser Einschränkungen ist, dass das Parsen von JSON schnell ist und keine Möglichkeit für Code-Injection bietet (eine Sicherheitsbedrohung).

Aufgrund dieser Einschränkungen kann JSON keine Klammern verwenden. Folglich ist eine Klammer in einer JSON-Zeichenfolge ein unzulässiges Zeichen.

Verwenden Sie aus folgenden Gründen immer das JSON-Format mit ajax:

  • Eine typische Ajax-Pipeline wird für JSON konfiguriert.
  • Die Verwendung von "eval ()" wird als Sicherheitsrisiko kritisiert.

Als Beispiel für eine Ajax-Pipeline wird ein Programm betrachtet, das einen Node= Server und einen jQuery-Client enthält. Das Client-Programm verwendet einen jQuery-Aufruf mit der Form $.ajax({dataType:'json',...etc.});. JQuery erstellt Ein jqXHR-Objekt für die spätere Verwendung packt und sendet die zugehörige Anforderung. Der Server akzeptiert die Anforderung, verarbeitet sie und ist dann zur Beantwortung bereit. Das Serverprogramm ruft die Methode res.json(data) auf, um die zu packen und zu senden Zurück auf der Clientseite akzeptiert jQuery die Antwort, konsultiert das zugehörige jqXHR-Objekt und verarbeitet die JSON-formatierten Daten. Dies alles funktioniert ohne manuelle Datenkonvertierung. Die Antwort erfordert keinen expliziten Aufruf von JSON.stringify () on der Node Server und kein expliziter Aufruf von JSON.parse () auf dem Client, das ist alles für Sie erledigt.

Die Verwendung von "eval" ist mit Sicherheitsrisiken bei der Codeinjektion verbunden. Man könnte meinen, dass es keine Möglichkeit gibt, aber Hacker können sehr kreativ werden. Auch "eval" ist problematisch für die Javascript-Optimierung.

Wenn Sie feststellen, dass Sie eine "stringify ()" - Funktion verwenden, beachten Sie, dass einige Funktionen mit diesem Namen Zeichenfolgen erstellen, die mit "eval" und nicht mit JSON kompatibel sind. In Node erhalten Sie beispielsweise die folgende Funktion, mit der Zeichenfolgen in einem mit "eval" kompatiblen Format erstellt werden:

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

Dies kann nützlich sein, aber es sei denn, Sie haben einen bestimmten Bedarf, ist es wahrscheinlich nicht das, was Sie wollen.

2
IAM_AL_X

Wenn Sie ASP.NET-Webdienste mit jQuery verwenden, stellen Sie sicher, dass in Ihrer web.config Folgendes enthalten ist:

<webServices>
    <protocols>
        <add name="HttpGet"/>
        <add name="HttpPost"/>
    </protocols>
</webServices>
2
Andreas Grech

In einer ColdFusion-Umgebung ist Enable Request Debugging Output in ColdFusion Administrator (unter Debugging & Logging> Debug Output Settings) aktiviert, was auch bei wohlgeformtem JSON zu einem Fehler führt. Debugging-Informationen werden mit den JSON-Daten zurückgegeben und machen sie daher ungültig.

1
Dave DuPlantis

Ich habe status = parseerror und xhr.status = 200 erhalten.

Das Problem war für mich, dass die URLs in der JSON-Antwort '\' auf '/' umgeschaltet haben, was dieses Problem behoben hat.

1
Brent

versuchen Sie es auch

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

in meinem Fall antwortet der Server mit einem unbekannten Zeichen vor '{'

1
valir

Wenn das Zurückgeben eines Arrays funktioniert und das Zurückgeben eines einzelnen Objekts nicht funktioniert, können Sie auch versuchen, Ihr einzelnes Objekt als Array zurückzugeben, das dieses einzelne Objekt enthält:

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

auf diese Weise geben Sie eine konsistente Datenstruktur zurück, ein Array von Objekten, unabhängig von der Datennutzlast.

ich sehe, dass Sie versucht haben, Ihr einzelnes Objekt in "Klammern" zu setzen, und schlage dies mit einem Beispiel vor, weil JavaScript natürlich [..] anders behandelt als (..).

1
David Alpert

Wenn der Error-Handler von jQuery aufgerufen wird und das XHR-Objekt "Parser-Fehler" enthält, ist dies wahrscheinlich ein Parser-Fehler, der vom Server zurückkommt.

Wenn Sie den Service ohne Parameter aufrufen und versuchen, einen Parameter zum Abrufen des einzelnen Datensatzes anzugeben, ist Ihr Szenario mit mehreren Ergebnissen fehlerhaft?

Von welchem ​​Backend kehrst du das zurück?

Bei ASMX-Diensten ist dies beispielsweise häufig der Fall, wenn Parameter anstelle einer JSON-Zeichenfolge als JSON-Objekt an jQuery übergeben werden. Wenn Sie jQuery ein tatsächliches JSON-Objekt für seinen Parameter "data" bereitstellen, serialisiert es dieses in standardmäßige und durch k, v getrennte Paare, anstatt es als JSON zu senden.

1
Dave Ward

jQuery-Drosseln auf bestimmten JSON-Schlüsseln. Ich habe dieses JSON-Snippet in PHP gesendet:

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

Das Umbenennen des Ergebnisschlüssels in etwas anderes funktioniert. Ich würde vermuten, dass dies eine reservierte Word-Kollision ist und ein Fehler in jQuery (1.4.2) sein könnte.

1
Jonathon Hill

In einigen meiner Implementierungen musste ich Folgendes hinzufügen:

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

das schien das Problem zu lösen. Eval oder nicht, es schien genau dasselbe für mich zu tun.

1
Jay

Ich kämpfte damit und verbrachte ein paar Stunden damit, dies herauszufinden, bis ich das Datenobjekt mit einem Firebug anzeigte.

var data = eval("(" + data.responseText + ")");
console.log(data.count);
0
webwiseguys