Ich mache Anfragen an meinen Server mit "jQuery.post()" und mein Server gibt JSON-Objekte zurück (wie "{ "var": "value", ... }"). Wenn jedoch einer der Werte ein einzelnes Anführungszeichen enthält (das ordnungsgemäß wie "" var": " value" " value" " }" maskiert ist), kann jQuery eine ansonsten gültige JSON-Zeichenfolge nicht parsen. Hier ist ein Beispiel dafür, was ich meine (in der Chrome-Konsole ausgeführt):
data = "{ \"status\": \"success\", \"newHtml\": \"Hello \\\'x\" }";
eval("x = " + data); // { newHtml: "Hello 'x", status: "success" }
$.parseJSON(data); // Invalid JSON: { "status": "success", "newHtml": "Hello \'x" }
Ist das normal? Gibt es keine Möglichkeit, ein einzelnes Anführungszeichen ordnungsgemäß über JSON zu übergeben?
Nach dem Zustandsdiagramm auf der JSON-Website sind nur maskierte doppelte Anführungszeichen erlaubt, nicht aber einfache Anführungszeichen. Einfache Anführungszeichen müssen nicht escaped werden:
Update - Weitere Informationen für Interessierte:
Douglas Crockford sagt nicht ausdrücklich, warum die JSON-Spezifikation keine escapeten einfachen Anführungszeichen innerhalb von Zeichenketten zulässt. In seiner Diskussion über JSON in Appendix E of JavaScript: The Good Parts schreibt er jedoch:
JSON's Designziele waren minimal, portabel, textuell und eine Untermenge von JavaScript. Je weniger wir uns einigen müssen, um zusammenzuarbeiten, desto leichter können wir zusammenarbeiten.
So hat er vielleicht beschlossen, nur die Definition von Zeichenketten in doppelten Anführungszeichen zuzulassen, da dies eine Regel weniger ist, der alle JSON-Implementierungen zustimmen müssen. Infolgedessen ist es unmöglich, dass ein einzelnes Anführungszeichen innerhalb einer Zeichenkette die Zeichenkette versehentlich beendet, da eine Zeichenkette per Definition nur durch ein doppeltes Anführungszeichen beendet werden kann. Daher ist es nicht erforderlich, in der formalen Spezifikation das Escaping eines einzelnen Anführungszeichens zuzulassen.
Die von den toString-Methoden erzeugten Texte entsprechen streng den JSON-Syntaxregeln. Die Konstruktoren sind nachsichtiger bei den Texten, die sie akzeptieren:
...
- Strings können mit ' (einfaches Anführungszeichen) zitiert werden.
Dies wird durch den JSONTokener Quellcode bestätigt. Die Methode nextString
akzeptiert escapte einfache Anführungszeichen und behandelt sie genauso wie doppelte Anführungszeichen:
public String nextString(char quote) throws JSONException {
char c;
StringBuffer sb = new StringBuffer();
for (;;) {
c = next();
switch (c) {
...
case '\\':
c = this.next();
switch (c) {
...
case '"':
case '\'':
case '\\':
case '/':
sb.append(c);
break;
...
Am Anfang der Methode steht ein informativer Kommentar:
Das formale JSON-Format erlaubt keine Zeichenketten in einfachen Anführungszeichen, aber eine Implementierung darf sie akzeptieren.
Einige Implementierungen akzeptieren also einfache Anführungszeichen - aber Sie sollten sich nicht darauf verlassen. Viele gängige Implementierungen sind in dieser Hinsicht recht restriktiv und lehnen JSON ab, das Zeichenketten in einfachen Anführungszeichen und/oder escapete einfache Anführungszeichen enthält.
Um auf die ursprüngliche Frage zurückzukommen: jQuery.parseJSON
versucht zunächst, den nativen JSON-Parser des Browsers oder eine geladene Bibliothek wie z.B. json2.js zu verwenden (die, nebenbei bemerkt, die Bibliothek ist, auf der die jQuery-Logik basiert, wenn JSON
nicht definiert ist). Daher kann jQuery nur so freizügig sein wie die zugrunde liegende Implementierung:
parseJSON: function( data ) {
...
// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
...
jQuery.error( "Invalid JSON: " + data );
},
Soweit ich weiß, halten sich diese Implementierungen nur an die offizielle JSON-Spezifikation und akzeptieren keine einfachen Anführungszeichen, also auch nicht jQuery.
Wenn Sie ein einzelnes Anführungszeichen innerhalb einer Zeichenkette benötigen, da "\' in der Spezifikation nicht definiert ist, verwenden Sie "\u0027". Siehe http://www.utf8-chartable.de/ für alle diese Zeichen.
edit: bitte entschuldigen Sie meine falsche Verwendung des Wortes Backticks in den Kommentaren. Ich meinte Backslash. Worauf ich hinaus will, ist, dass es für den Fall, dass Sie verschachtelte Strings innerhalb anderer Strings haben, nützlicher und lesbarer sein kann, Unicode statt vieler Backslashes zu verwenden, um ein einzelnes Anführungszeichen zu entkommen. Wenn Sie jedoch nicht verschachtelt sind, ist es wirklich einfacher, einfach ein einfaches altes Anführungszeichen zu verwenden.
Interessant. Wie generieren Sie Ihr JSON auf der Serverseite? Verwenden Sie eine Bibliotheksfunktion (z. B. "json_encode" in PHP), oder erstellen Sie die JSON-Zeichenfolge von Hand?
Das einzige, was mir auffällt, ist das Escape-Apostroph (\'
). Da Sie doppelte Anführungszeichen verwenden, was Sie auch tun sollten, besteht keine Notwendigkeit, einfache Anführungszeichen zu entschlüsseln. Ich kann nicht überprüfen, ob das tatsächlich die Ursache für Ihren jQuery-Fehler ist, da ich selbst noch nicht auf Version 1.4.1 aktualisiert habe.