wake-up-neo.com

jQuery.parseJSON gibt den Fehler "Ungültiger JSON" aus, da in JSON ein einfaches Anführungszeichen vorliegt

Ich mache mit jQuery.post() Anforderungen an meinen Server und mein Server gibt JSON-Objekte zurück (wie { "var": "value", ... }). Wenn jedoch einer der Werte ein einzelnes Anführungszeichen enthält (ordnungsgemäß mit Escapezeichen wie \' versehen), kann jQuery keinen ansonsten gültigen JSON-String analysieren. Hier ist ein Beispiel für das, was ich meine ( in Chrome-Konsole gemacht ):

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 Angebot korrekt über JSON zu übergeben?

199
Felix

Gemäß dem Zustandsmaschinendiagramm auf der JSON-Website sind nur doppelte Anführungszeichen mit Escapezeichen zulässig, keine einfachen Anführungszeichen. Anführungszeichen müssen nicht mit Escapezeichen versehen werden:

http://www.json.org/string.gif


Aktualisieren - Weitere Informationen für Interessierte:


Douglas Crockford sagt nicht ausdrücklich aus, warum die JSON-Spezifikation es nicht erlaubt, einzelne Anführungszeichen in Strings zu verwenden. Während seiner Diskussion über JSON in Anhang E von JavaScript: The Good Parts schreibt er:

Die Design-Ziele von JSON waren minimal, portabel, textuell und eine Teilmenge von JavaScript. Je weniger wir uns einig sein müssen, um interoperieren zu können, desto einfacher können wir zusammenarbeiten.

Vielleicht hat er sich entschieden, Strings nur in Anführungszeichen zu definieren, da dies eine Regel weniger ist, auf die sich alle JSON-Implementierungen einigen müssen. Daher kann ein einzelnes Anführungszeichen in einer Zeichenfolge nicht versehentlich die Zeichenfolge beenden, da eine Zeichenfolge per Definition nur durch ein Anführungszeichen abgeschlossen werden kann. Daher ist es nicht erforderlich, in der formalen Spezifikation ein einzelnes Anführungszeichen zu umgehen.


Etwas tiefer zu graben, ist die Implementierung von JSON für Java von Crockford org.json zulässiger und do erlaubt einfache Anführungszeichen:

Die von den toString-Methoden erstellten Texte entsprechen streng den JSON-Syntaxregeln. Die Konstrukteure sind in den Texten, die sie akzeptieren werden, verzeihender:

...

  • Zeichenketten können mit '(einfaches Anführungszeichen) zitiert werden.

Dies wird durch den Quellcode JSONTokener bestätigt. Die nextString-Methode akzeptiert einzelne Zeichen in Anführungszeichen und behandelt sie wie 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;
        ...

An der Spitze der Methode steht ein informativer Kommentar:

Das formale JSON-Format erlaubt keine Strings in einfachen Anführungszeichen, aber eine Implementierung darf sie akzeptieren.

Einige Implementierungen akzeptieren also einfache Anführungszeichen - aber darauf sollten Sie sich nicht verlassen. Viele populäre Implementierungen sind in dieser Hinsicht ziemlich restriktiv und lehnen JSON ab, das einzelne Anführungszeichen und/oder einzelne Anführungszeichen enthält.


Um dies wieder an die ursprüngliche Frage zu knüpfen, versucht jQuery.parseJSON zunächst, den nativen JSON-Parser des Browsers oder eine geladene Bibliothek wie json2.js zu verwenden (wo auf einer Seite die Bibliothek jQuery steht Die Logik basiert darauf, ob JSON nicht definiert ist. Daher kann jQuery nur so zulässig 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ß, entsprechen diese Implementierungen nur der offiziellen JSON-Spezifikation und akzeptieren keine einfachen Anführungszeichen. Daher auch nicht jQuery.

323
Justin Ethier

Wenn Sie ein einzelnes Anführungszeichen innerhalb eines Strings benötigen, da\'durch die Spezifikation nicht definiert ist, verwenden Sie \u0027 unter http://www.utf8-chartable.de/ für alle

bearbeiten: Bitte entschuldigen Sie meinen Missbrauch der Word-Backticks in den Kommentaren. Ich meinte Backslash. Mein Punkt hier ist, dass, wenn Sie Strings in anderen Strings verschachtelt haben, es meiner Meinung nach sinnvoller und lesbarer sein kann, Unicode anstelle vieler Backslashes zu verwenden, um einem einzelnen Anführungszeichen zu entgehen. Wenn Sie nicht verschachtelt sind, ist es wirklich einfacher, ein einfaches altes Zitat dort einzugeben.

16
slf

Wenn Sie ein einzelnes Angebot in einer Abfrage senden

empid = " T'via"
empid =escape(empid)

Wenn Sie den Wert einschließlich eines einzelnen Angebots erhalten

var xxx  = request.QueryString("empid")
xxx= unscape(xxx)

Wenn Sie den Wert suchen/einfügen möchten, der ein einzelnes Anführungszeichen in einer Abfrage enthält xxx=Replace(empid,"'","''")

3
BehranG BinA

Ich verstehe, wo das Problem liegt, und wenn ich mir die Spezifikationen ansehe, ist klar, dass nicht verstrichene einfache Anführungszeichen korrekt analysiert werden sollten.

Ich verwende die jQuery.parseJSON-Funktion von jquery, um die JSON-Zeichenfolge zu analysieren, aber immer noch den Parser-Fehler, wenn in den Daten, die mit json_encode vorbereitet werden, ein einzelnes Anführungszeichen steht.

Könnte es ein Fehler in meiner Implementierung sein, der so aussieht (PHP-Server-Seite):

$data = array();

$elem = array();
$elem['name'] = 'Erik';
$elem['position'] = 'PHP Programmer';
$data[] = json_encode($elem);

$elem = array();
$elem['name'] = 'Carl';
$elem['position'] = 'C Programmer';
$data[] = json_encode($elem);

$jsonString = "[" . implode(", ", $data) . "]";

Der letzte Schritt ist, dass ich die JSON-codierte Zeichenfolge in einer JS-Variablen speichere:

<script type="text/javascript">
employees = jQuery.parseJSON('<?=$marker; ?>');
</script>

Wenn ich "" anstelle von "" verwende, wird immer noch ein Fehler ausgegeben.

LÖSUNG:

Das einzige, was für mich funktionierte, war die Verwendung der Bitmaske JSON_HEX_APOS, um die einzelnen Anführungszeichen wie folgt zu konvertieren:

json_encode($tmp, JSON_HEX_APOS);

Gibt es eine andere Möglichkeit, dieses Problem anzugehen? Ist mein Code falsch oder schlecht geschrieben?

Vielen Dank

3
Erik Čerpnjak

Ein ähnliches Problem wurde bei der Verwendung von CakePHP zur Ausgabe eines JavaScript-Skriptblocks mit dem json_encode von PHP festgestellt. $contractorCompanies enthält Werte, die einfache Anführungszeichen enthalten und wie oben erläutert und erwartet json_encode($contractorCompanies) sie nicht aufgrund ihrer gültigen JSON entgeht.

<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".(json_encode($contractorCompanies)."' );"); ?>

Durch Hinzufügen von addlashes () um die JSON-codierte Zeichenfolge können Sie die Anführungszeichen mit Escape-Zeichen versehen, sodass Cake/PHP das richtige Javascript für den Browser verwendet. JS-Fehler verschwinden.

<?php $this->Html->scriptBlock("var contractorCompanies = jQuery.parseJSON( '".addslashes(json_encode($contractorCompanies))."' );"); ?>
2
chopstik

Ich habe versucht, ein JSON-Objekt aus einer XHR-Anforderung in ein HTML5-Datenattribut zu speichern. Ich habe viele der oben genannten Lösungen ohne Erfolg ausprobiert.

Am Ende habe ich das einfache Anführungszeichen ' durch den Code &#39; mit einem Regex ersetzt, nachdem die stringify () -Methode folgendermaßen aufgerufen wurde: 

var productToString = JSON.stringify(productObject);
var quoteReplaced = productToString.replace(/'/g, "&#39;");
var anchor = '<a data-product=\'' + quoteReplaced + '\' href=\'#\'>' + productObject.name + '</a>';
// Here you can use the "anchor" variable to update your DOM element.
0
BoCyrill

Interessant. Wie generieren Sie Ihre JSON auf der Serverseite? Verwenden Sie eine Bibliotheksfunktion (z. B. json_encode in PHP) oder erstellen Sie den JSON-String von Hand?

Das einzige, was meine Aufmerksamkeit auf sich zieht, ist der Fluchtapostroph (\'). Da Sie doppelte Anführungszeichen verwenden, wie Sie es eigentlich sollten, müssen Sie die einfachen Anführungszeichen nicht entgehen lassen. Ich kann nicht überprüfen, ob dies tatsächlich die Ursache für Ihren jQuery-Fehler ist, da ich selbst noch nicht auf Version 1.4.1 aktualisiert wurde.

0
Aistina