Et AJAX-skjema forventer JSON, men får HTML: gå gjennom svaret steg for steg
En 200-respons er ikke bevis på JSON. Gå gjennom Nettverks-panelet steg for steg og skill feil i transport, representasjon og kontrakt.
Skjemaet sendes, spinneren vises, og konsollen sier at det er et uventet token < i JSON på posisjon 0. Siden lastes fint, og derfor er det første instinktet å skylde på parseren eller tunnelen. Vanligvis er ingen av dem involvert: innsendingen er en annen forespørsel enn sidelasten, og den kom tilbake med noe som ikke er JSON. Arbeid i den rekkefølgen nettleseren faktisk avdekker det i, fordi de fire mulige svarene krever fire forskjellige rettelser.
Trinn 1: fang innsendingen som faktisk skjedde
Åpne Nettverks-panelet før du sender, sett loggen til å bevare oppføringer på tvers av navigasjon, og gjør deretter én ufarlig testinnsending på en konto du har lov til å bruke. Velg forespørselen som skjemaet selv startet, ikke sidens dokumentforespørsel.
Vær forsiktig med filtre. Et XHR- eller Fetch-filter er praktisk, men hvis rammeverket fortsatt sender gjennom en skjult iframe eller et dynamisk opprettet skjema, skjuler filteret den eneste forespørselen som betyr noe. Send først én gang uten filter og se hva som dukket opp.
For den valgte forespørselen, noter seks ting før du tolker noe: metoden, hele URL-en med spørringsstrengen, statusen, omdirigeringskjeden, Content-Type for svaret og de første linjene i kroppen. Referansen for Nettverks-panelet i Chrome DevTools dekker visningene Headers, Response og Initiator der dette ligger, og de tilsvarende panelene i andre nettlesere viser de samme feltene.
Trinn 2: bekreft at det er forespørselen du tror
Et overraskende antall JSON-feil er egentlig rutingfeil. Hvis innsendingsbehandleren kaster før den kaller preventDefault, utfører nettleseren en naturlig skjema-POST til adressen action-attributtet angir, og serveren svarer med en full HTML-side. Behandleren kjører aldri, så det ble aldri bedt om JSON.
Sammenlign URL-en i panelet med URL-en JavaScriptet ditt kaller. Se etter en omdirigering som ender et annet sted, en manglende eller ekstra skråstrek på slutten, et metodeavvik der behandleren sender GET og endepunktet godtar POST, eller et skjema som sender til en relativ sti fra en side som har flyttet seg. Følg omdirigeringskjeden til slutten og noter den endelige URL-en, ikke den første.
Kontroller deretter initiatoren. Hvis forespørselen kom fra en dokumentnavigasjon og ikke fra skriptet ditt, har du allerede funnet problemet, og ingen endring i en svarparser vil hjelpe.
Trinn 3: sorter resultatet i fire kategorier
Hvert resultat hører til nøyaktig én av disse, og kategorien avgjør hvor du ser neste gang.
| What you see | Category | Where to look |
|---|---|---|
| Request never finishes, TLS or connection error | No usable response | Endpoint reachability, certificate, front-end timeout |
| Request completes, script gets an opaque failure | Access blocked | Cross-origin policy, credentials mode, missing response header |
| 200 with an HTML body or a login form | Wrong representation | Redirect, expired session, route fallback, error handler |
| Body begins with a notice then valid JSON | Wrong representation | Server-side warning output before serialisation |
| Valid JSON, framework rejects it | Contract mismatch | Envelope shape, field names, value types |
De midterste radene er dem folk feildiagnostiserer, fordi statusen er 200. En påloggingsside man når etter en omdirigering, er et fullstendig godt HTTP-svar og et svært dårlig JSON-dokument. Innholdstypen application/json reparerer ikke det: det er en etikett, og en feilmerket kropp lar seg fortsatt ikke parse. Tilgang blokkert er raden som ser ut som en fullført forespørsel: panelet viser en status, men retningslinjen for kryss-opphav holder kroppen tilbake, så for skriptet som kaller er den like ubrukelig som en tidsavbrudd.
Den fjerde raden er like vanlig på eldre PHP- og rammeverksstakker. En avskrivningsadvarsel som skrives ut før den kodede lasten, gir en kropp som ingen JSON-parser godtar, og ofte er den advarselen hele forklaringen.
Trinn 4: les parserfeilen bokstavelig
Feilteksten navngir det første tegnet som brøt parsingen, og det identifiserer vanligvis kategorien uten noen gjetning.
| Error text (Chrome/V8) | What it means |
|---|---|
| Unexpected token < in JSON at position 0 | The body starts with markup: an HTML page or an error document |
| Unexpected end of JSON input | Empty body, or the response was truncated |
| Unexpected token o in JSON at position 1 | You parsed something already parsed, typically an object rather than text |
| Unexpected token u | The body starts with the bare word undefined, usually an empty response rendered as a string |
En tom kropp med 200 er et eget tilfelle: endepunktet kjørte, produserte ingenting, og noe lenger ned behandlet det som suksess. Det er en kontraktorfeil i applikasjonen og ikke i transporten, og den hører hjemme i neste trinn, ikke i proxyen. Firefox og Safari formulerer de samme fire feilene annerledes, så match på tegnet eller på den tomme kroppen og ikke på den eksakte strengen.
Trinn 5: rett opp laget bevisene peker på
For et rutingproblem, rett forespørselen: rett action, hindre behandleren i å falle gjennom, få endepunkt og metode til å stemme, og test på nytt. For et representasjonsproblem, rett det som produserte kroppen, og finn ut hvorfor et feildokument returneres der data var forventet. For et kontraktorproblem, les rammeverkets faktiske forventede struktur for versjonen du kjører, og form svaret etter den i stedet for å løsne klienten.
Et svar med blokkert tilgang trenger sin egen gjennomgang, fordi forespørselen selv kan være riktig og kroppen kanskje aldri når koden din. Sammenlign svarets Access-Control-Allow-Origin med den nøyaktige Origin nettleseren sendte, og husk at et jokertegn ikke tilfredsstiller en forespørsel med legitimasjon. Par credentials: 'include' på klienten med Access-Control-Allow-Credentials: true på serveren, og sjekk om kallet brukte no-cors-modus, der en ugjennomsiktig kropp er det dokumenterte resultatet og ikke en feil.
Å erstatte parseren med noe mer ettergivende er den ene rettelsen man bør unngå. Å evaluere svaret som kode, eller å skrelle tekst til det lar seg parse, skjuler kontraktavviket og legger til en injeksjonsflate i bytte mot stillhet. På samme måte må statusen kontrolleres atskilt fra kroppen: en 200 med et feilobjekt på applikasjonsnivå er normalt i mange API-er og må håndteres ved å lese lasten.
Når du trenger hjelp fra noen andre, del en minimal oppføring — metode, URL, status, endelig URL etter omdirigeringer, svarets innholdstype, kroppens form og den forventede kontrakten — i stedet for en rå eksport. Nettverksarkiver inneholder informasjonskapsler, tokens, spørringsstrenger og personopplysningene som var i skjemaet, og en automatisk renser er ikke en gjennomgang.
- Fang forespørselen uten filter før du endrer noen kode.
- Bekreft at initiatoren var skriptet ditt og at den endelige URL-en er endepunktet ditt.
- Klassifiser svaret før du rører parseren.
- Rett ruting, tilgang, representasjon eller kontrakt, og aldri ved å løsne parseren.