Das Formular wird abgeschickt, der Ladekreis erscheint, und die Konsole meldet ein unerwartetes Token < in JSON an Position 0. Die Seite selbst lädt sauber, deshalb lautet der erste Reflex, den Parser oder den Tunnel zu beschuldigen. Meist ist keiner von beiden beteiligt: das Absenden ist eine andere Anfrage als das Laden der Seite, und zurück kam etwas, das kein JSON ist. Arbeiten Sie in der Reihenfolge, in der der Browser es tatsächlich offenlegt, denn die vier möglichen Antworten verlangen vier verschiedene Korrekturen.

Schritt 1: die Absendung erfassen, die wirklich stattfand

Öffnen Sie das Netzwerk-Panel, bevor Sie absenden, stellen Sie das Protokoll so ein, dass Einträge über Navigationen hinweg erhalten bleiben, und machen Sie dann eine harmlose Testabsendung mit einem Konto, das Sie verwenden dürfen. Wählen Sie die Anfrage, die das Formular selbst ausgelöst hat, nicht die Dokumentanfrage der Seite.

Seien Sie vorsichtig mit Filtern. Ein XHR- oder Fetch-Filter ist bequem, aber wenn das Framework weiterhin über ein verstecktes iframe oder ein dynamisch erzeugtes Formular absendet, verdeckt der Filter die einzige Anfrage, auf die es ankommt. Senden Sie zuerst einmal ungefiltert und schauen Sie, was erschienen ist.

Notieren Sie für die gewählte Anfrage sechs Dinge, bevor Sie irgendetwas deuten: Methode, vollständige URL einschließlich Query-String, Status, die Weiterleitungskette, den Content-Type der Antwort und die ersten Zeilen des Bodys. Die Referenz zum Netzwerk-Panel von Chrome DevTools beschreibt die Ansichten Headers, Response und Initiator, in denen das steht, und die entsprechenden Panels anderer Browser zeigen dieselben Felder.

Schritt 2: bestätigen, dass es die erwartete Anfrage ist

Überraschend viele JSON-Fehler sind in Wahrheit Routing-Fehler. Wenn der Submit-Handler eine Ausnahme wirft, bevor er preventDefault aufruft, führt der Browser einen nativen Formular-POST an das Ziel aus dem action-Attribut aus, und der Server antwortet mit einer vollständigen HTML-Seite. Der Handler läuft nie, es wurde also nie JSON angefordert.

Vergleichen Sie die URL im Panel mit der URL, die Ihr JavaScript aufruft. Achten Sie auf eine Weiterleitung, die anderswo endet, einen fehlenden oder überzähligen Schrägstrich am Ende, eine Methodenabweichung, bei der der Handler GET sendet und der Endpunkt POST annimmt, oder ein Formular, das an einen relativen Pfad von einer verschobenen Seite sendet. Verfolgen Sie die Weiterleitungskette bis zum Ende und notieren Sie die endgültige URL, nicht die erste.

Prüfen Sie danach den Initiator. Kam die Anfrage aus einer Dokumentnavigation statt aus Ihrem Skript, haben Sie das Problem bereits gefunden, und keine Änderung an einem Antwortparser hilft.

Schritt 3: das Ergebnis in vier Kategorien einordnen

Jedes Ergebnis gehört genau in eine davon, und die Kategorie entscheidet, wo Sie als Nächstes nachsehen.

What you seeCategoryWhere to look
Request never finishes, TLS or connection errorNo usable responseEndpoint reachability, certificate, front-end timeout
Request completes, script gets an opaque failureAccess blockedCross-origin policy, credentials mode, missing response header
200 with an HTML body or a login formWrong representationRedirect, expired session, route fallback, error handler
Body begins with a notice then valid JSONWrong representationServer-side warning output before serialisation
Valid JSON, framework rejects itContract mismatchEnvelope shape, field names, value types

Die mittleren Zeilen werden am häufigsten falsch diagnostiziert, weil der Status 200 ist. Eine Anmeldeseite, die man nach einer Weiterleitung erreicht, ist eine völlig gute HTTP-Antwort und ein sehr schlechtes JSON-Dokument. Der Content-Type application/json repariert das nicht: Er ist ein Etikett, und ein falsch etikettierter Body lässt sich weiterhin nicht parsen. Zugriff blockiert ist die Zeile, die wie eine abgeschlossene Anfrage aussieht: Das Panel zeigt einen Status, aber die Cross-Origin-Policy hält den Body zurück, für das aufrufende Skript ist er also so unbrauchbar wie ein Timeout.

Die vierte Zeile ist auf älteren PHP- und Framework-Stapeln ebenso verbreitet. Eine Deprecation-Warnung, die vor der kodierten Nutzlast ausgegeben wird, erzeugt einen Body, den kein JSON-Parser annimmt, und oft ist die Warnung die ganze Erklärung.

Schritt 4: die Parser-Meldung wörtlich lesen

Der Fehlertext nennt das erste Zeichen, das das Parsen gebrochen hat, und das bestimmt die Kategorie meist ohne jedes Raten.

Error text (Chrome/V8)What it means
Unexpected token < in JSON at position 0The body starts with markup: an HTML page or an error document
Unexpected end of JSON inputEmpty body, or the response was truncated
Unexpected token o in JSON at position 1You parsed something already parsed, typically an object rather than text
Unexpected token uThe body starts with the bare word undefined, usually an empty response rendered as a string

Ein leerer Body mit einem 200 ist ein eigener Fall: Der Endpunkt lief, erzeugte nichts, und etwas weiter unten hat das als Erfolg behandelt. Das ist ein Vertragsfehler der Anwendung und kein Transportfehler, und er gehört in den nächsten Schritt statt in den Proxy. Firefox und Safari formulieren dieselben vier Fehler anders, richten Sie sich also nach dem Zeichen oder dem leeren Body und nicht nach der exakten Zeichenkette.

Schritt 5: die Schicht korrigieren, auf die die Belege zeigen

Bei einem Routing-Problem korrigieren Sie die Anfrage: action berichtigen, den Handler nicht durchfallen lassen, Endpunkt und Methode in Übereinstimmung bringen und erneut testen. Bei einem Darstellungsproblem korrigieren Sie das, was den Body erzeugt hat, und finden Sie heraus, warum ein Fehlerdokument zurückkommt, wo Daten erwartet wurden. Bei einem Vertragsproblem lesen Sie die tatsächlich erwartete Struktur des Frameworks für die laufende Version und formen die Antwort danach, statt den Client zu lockern.

Eine Antwort mit blockiertem Zugriff braucht einen eigenen Durchgang, weil die Anfrage selbst korrekt sein kann und der Body Ihren Code womöglich nie erreicht. Vergleichen Sie das Access-Control-Allow-Origin der Antwort mit dem genauen Origin, das der Browser gesendet hat, und denken Sie daran, dass ein Platzhalter eine Anfrage mit Anmeldedaten nicht erfüllt. Paaren Sie credentials: 'include' auf dem Client mit Access-Control-Allow-Credentials: true auf dem Server und prüfen Sie, ob der Aufruf den Modus no-cors verwendet hat, in dem ein undurchsichtiger Body das dokumentierte Ergebnis und kein Fehler ist.

Den Parser durch etwas Nachsichtigeres zu ersetzen ist die eine Korrektur, die man vermeiden sollte. Die Antwort als Code auszuwerten oder Text abzutragen, bis sie sich parsen lässt, verdeckt die Vertragsabweichung und fügt als Gegenleistung für Stille eine Angriffsfläche hinzu. Ebenso muss der Status getrennt vom Body geprüft werden: Ein 200 mit einem Fehlerobjekt auf Anwendungsebene ist in vielen APIs normal und muss durch Lesen der Nutzlast behandelt werden.

Wenn Sie Hilfe von jemand anderem brauchen, teilen Sie einen minimalen Datensatz — Methode, URL, Status, endgültige URL nach Weiterleitungen, Content-Type der Antwort, Form des Bodys und den erwarteten Vertrag — statt eines rohen Exports. Netzwerkarchive enthalten Cookies, Tokens, Query-Strings und die personenbezogenen Daten aus dem Formular, und ein automatischer Bereiniger ist keine Prüfung.

  • Erfassen Sie die Anfrage ungefiltert, bevor Sie irgendeinen Code ändern.
  • Bestätigen Sie, dass der Initiator Ihr Skript war und die endgültige URL Ihr Endpunkt ist.
  • Klassifizieren Sie die Antwort, bevor Sie den Parser anfassen.
  • Korrigieren Sie Routing, Zugriff, Darstellung oder Vertrag, und niemals durch Lockerung des Parsers.

Ähnliche Artikel