Eit AJAX-skjema ventar JSON, men får HTML: gå gjennom svaret steg for steg
Eit svar med status 200 er ikkje prov på at det er JSON. Gå gjennom Nettverk-panelet steg for steg og skil feil i transport, framstilling og kontrakt.
Skjemaet blir sendt, snurra dukkar opp, og konsollen seier at det er eit uventa teikn < i JSON på posisjon 0. Sida sjølv lastar fint, og difor er det første innskotet å leggje skulda på parsaren eller tunnelen. Vanlegvis er ingen av dei med: innsendinga er ei anna førespurnad enn sidelastinga, og ho kom tilbake med noko som ikkje er JSON. Arbeid i den rekkjefølgja nettlesaren faktisk avdekkjer det i, for dei fire moglege svara krev fire ulike rettingar.
Steg 1: fang innsendinga som faktisk skjedde
Opne Nettverk-panelet før du sender, set loggen til å halde på oppføringar på tvers av navigasjon, og gjer så éi ufarleg prøveinnsending på ein konto du har lov til å bruke. Vel førespurnaden som skjemaet sjølv starta, ikkje dokumentførespurnaden til sida.
Ver varsam med filter. Eit XHR- eller Fetch-filter er praktisk, men dersom rammeverket framleis sender gjennom ein skjult iframe eller eit dynamisk oppretta skjema, vil filteret gøyme den einaste førespurnaden som tel. Send fyrst éin gong utan filter og sjå kva som dukka opp.
For den valde førespurnaden, skriv ned seks ting før du tolkar noko: metoden, heile URL-en med spørjestrengen, statusen, omdirigeringskjeda, Content-Type for svaret og dei første linjene i kroppen. Referansen for Nettverk-panelet i Chrome DevTools dekkjer visingane Headers, Response og Initiator der dette ligg, og dei tilsvarande panela i andre nettlesarar viser dei same felta.
Steg 2: stadfest at det er førespurnaden du trur
Eit overraskande tal på JSON-feil er eigentleg rutefeil. Dersom innsendingshandsamaren kastar før han kallar preventDefault, gjer nettlesaren ein naturleg skjema-POST til adressa som action-attributtet seier, og tenaren svarar med ei full HTML-side. Handsamaren køyrer aldri, så det vart aldri bede om JSON.
Samanlikn URL-en i panelet med URL-en JavaScriptet ditt kallar. Sjå etter ei omdirigering som endar ein annan stad, ei manglande eller ekstra skråstrek til slutt, eit metodeavvik der handsamaren sender GET og endepunktet tek imot POST, eller eit skjema som sender til ein relativ stig frå ei side som har flytta seg. Følg omdirigeringskjeda til endes og skriv ned den endelege URL-en, ikkje den første.
Kontroller så initiatoren. Dersom førespurnaden kom frå ein dokumentnavigasjon og ikkje frå skriptet ditt, har du alt funne problemet, og inga endring i ein svarparsar vil hjelpe.
Steg 3: del resultatet i fire kategoriar
Kvart resultat høyrer til nøyaktig éin av desse, og kategorien avgjer kvar du ser neste gong.
| 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 |
Dei midtre radene er dei folk feildiagnostiserer, fordi statusen er 200. Ei innloggingsside ein når etter ei omdirigering, er eit fullt ut godt HTTP-svar og eit svært dårleg JSON-dokument. Innhaldstypen application/json reparerer ikkje det: han er ein etikett, og ein feilmerkt kropp let seg framleis ikkje parse. Tilgang blokkert er rada som ser ut som ei fullført førespurnad: panelet viser ein status, men retningslinja for kryss-opphav held kroppen tilbake, så for skriptet som kallar er han like ubrukeleg som ein tidsavbrot.
Den fjerde rada er like vanleg på eldre PHP- og rammeverksstakkar. Ei avskrivingsåtvaring som blir skriven ut før den koda lasta, gjev ein kropp som ingen JSON-parsar godtek, og ofte er den åtvaringa heile forklaringa.
Steg 4: les parsarfeilen bokstaveleg
Feilteksten namngjev det første teiknet som braut parseringa, og det identifiserer vanlegvis kategorien utan noka gissing.
| 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 |
Ein tom kropp med 200 er eit eige tilfelle: endepunktet køyrde, produserte ingenting, og noko lenger nede handsama det som suksess. Det er ein kontraktfeil i applikasjonen og ikkje i transporten, og han høyrer heime i neste steg, ikkje i proxyen. Firefox og Safari formulerer dei same fire feila annleis, så match på teiknet eller på den tomme kroppen og ikkje på den eksakte strengen.
Steg 5: rett opp laget prova peikar på
For eit ruteproblem, rett førespurnaden: rett action, hindre handsamaren i å falle gjennom, få endepunkt og metode til å stemme, og test på nytt. For eit framstillingsproblem, rett det som produserte kroppen, og finn ut kvifor eit feildokument blir sendt tilbake der data var venta. For eit kontraktproblem, les den faktiske venta strukturen til rammeverket for versjonen du køyrer, og form svaret etter han i staden for å løysne klienten.
Eit svar med blokkert tilgang treng si eiga runde, fordi førespurnaden sjølv kan vere rett og kroppen kanskje aldri når koden din. Samanlikn Access-Control-Allow-Origin i svaret med den nøyaktige Origin nettlesaren sende, og hugs at eit jokarteikn ikkje oppfyller ein førespurnad med innloggingsdata. Para credentials: 'include' på klienten med Access-Control-Allow-Credentials: true på tenaren, og sjekk om kallet brukte no-cors-modus, der ein ugjennomsiktig kropp er det dokumenterte resultatet og ikkje ein feil.
Å bytte ut parsaren med noko meir ettergjevande er den eine rettinga ein bør unngå. Å vurdere svaret som kode, eller å skrella tekst til det let seg parse, gøymer kontraktavviket og legg til ei injeksjonsflate i byte for stille. På same måte må statusen kontrollerast skilt frå kroppen: ein 200 med eit feilobjekt på applikasjonsnivå er normalt i mange API-ar og må handsamast ved å lese lasta.
Når du treng hjelp frå nokon andre, del ei minimal oppføring — metode, URL, status, endeleg URL etter omdirigeringar, innhaldstypen i svaret, forma på kroppen og den venta kontrakten — i staden for ein rå eksport. Nettverksarkiv inneheld informasjonskapslar, token, spørjestrengar og personopplysningane som var i skjemaet, og ein automatisk reinskar er ikkje ei gjennomgang.
- Fang førespurnaden utan filter før du endrar nokon kode.
- Stadfest at initiatoren var skriptet ditt og at den endelege URL-en er endepunktet ditt.
- Klassifiser svaret før du rører parsaren.
- Rett ruting, tilgang, framstilling eller kontrakt, og aldri ved å løysne parsaren.