AJAX forma tikisi JSON, bet gauna HTML: peržiūrėkite atsakymą žingsnis po žingsnio
200 atsakymas neįrodo, kad tai JSON. Pereikite tinklo skydelį žingsnis po žingsnio ir atskirkite transportavimo, pateikimo ir sutarties gedimus.
Forma išsiunčiama, pasirodo suktukas, o konsolė sako, kad JSON 0 pozicijoje yra netikėtas simbolis <. Pats puslapis įkeliamas gerai, todėl pirmas instinktas kaltinti analizatorių ar tunelį. Paprastai nė vienas nedalyvauja: siuntimas yra kitas užklausimas nei puslapio įkėlimas, ir jis grįžo su tuo, kas nėra JSON. Dirbkite ta tvarka, kuria naršyklė tai iš tikrųjų atskleidžia, nes keturi galimi atsakymai reikalauja keturių skirtingų pataisymų.
1 žingsnis: užfiksuokite siuntimą, kuris tikrai įvyko
Atidarykite tinklo skydelį prieš siųsdami, nustatykite žurnalą taip, kad įrašai būtų saugomi perėjus tarp puslapių, ir tada atlikite vieną nekenksmingą bandomąjį siuntimą paskyroje, kurią leidžiama naudoti. Pasirinkite užklausą, kurią inicijavo pati forma, o ne puslapio dokumento užklausą.
Saugokitės filtrų. XHR arba Fetch filtras patogus, bet jei karkasas vis dar siunčia per paslėptą iframe arba dinamiškai sukurtą formą, filtras paslėps vienintelį svarbų užklausą. Pirmiausia siųskite kartą be filtro ir pažiūrėkite, kas pasirodė.
Pasirinktai užklausai užsirašykite šešis dalykus prieš bet kokį aiškinimą: metodą, visą URL su užklausos eilute, būseną, peradresavimų grandinę, atsakymo Content-Type ir kūno pirmąsias eilutes. Chrome DevTools tinklo skydelio nuoroda apima Headers, Response ir Initiator rodinius, kur tai yra, o kitų naršyklių atitinkami skydeliai rodo tuos pačius laukus.
2 žingsnis: patvirtinkite, kad tai ta užklausa
Stebėtinai daug JSON klaidų iš tikrųjų yra maršrutizavimo klaidos. Jei siuntimo apdorotojas išmeta išimtį prieš iškviesdamas preventDefault, naršyklė atlieka savąjį formos POST į adresą, nurodytą action atributo, o serveris atsako visu HTML puslapiu. Apdorotojas niekada nepasileidžia, taigi JSON niekada nebuvo paprašytas.
Palyginkite skydelyje esantį URL su tuo, kurį kviečia jūsų JavaScript. Ieškokite peradresavimo, kuris baigiasi kitur, trūkstamo arba nereikalingo galinio pasvirojo brūkšnio, metodo neatitikimo, kai apdorotojas siunčia GET, o galinis taškas priima POST, arba formos, kuri siunčia santykiniu keliu iš perkeltos puslapio. Sekite peradresavimų grandinę iki galo ir užrašykite galutinį URL, ne pirmąjį.
Tada patikrinkite iniciatorių. Jei užklausa atėjo iš dokumento navigacijos, o ne iš jūsų scenarijaus, problemą jau radote, ir joks atsakymo analizatoriaus pakeitimas nepadės.
3 žingsnis: suskirstykite rezultatą į keturias kategorijas
Kiekvienas rezultatas priklauso tiksliai vienai iš jų, o kategorija nusprendžia, kur žiūrėti toliau.
| 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 |
Vidurinės eilutės yra tos, kurias žmonės diagnozuoja neteisingai, nes būsena yra 200. Prisijungimo puslapis, pasiektas po peradresavimo, yra visiškai geras HTTP atsakymas ir labai blogas JSON dokumentas. Turinio tipas application/json to nesutvarko: tai tik etiketė, o neteisingai pažymėtas kūnas vis tiek neanalizuojamas. Prieiga užblokuota yra eilutė, kuri atrodo kaip baigtas užklausimas: skydelis rodo būseną, bet kryžminės kilmės politika sulaiko kūną, todėl kviečiančiam scenarijui ji tokia pat nenaudinga kaip laiko limitas.
Ketvirta eilutė taip pat dažna senesniuose PHP ir karkasų rinkiniuose. Įspėjimas apie pasenimą, atspausdintas prieš užkoduotą turinį, sukuria kūną, kurio nepriims joks JSON analizatorius, ir dažnai tas įspėjimas yra visas paaiškinimas.
4 žingsnis: skaitykite analizatoriaus klaidą pažodžiui
Klaidos tekstas įvardija pirmąjį simbolį, kuris sulaužė analizę, ir tai paprastai nustato kategoriją be jokių spėliojimų.
| 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 |
Tuščias kūnas su 200 yra atskiras atvejis: galinis taškas veikė, nieko nesukūrė, o kažkas žemiau tai priėmė kaip sėkmę. Tai programos sutarties, o ne transportavimo gedimas, ir jo vieta kitame žingsnyje, o ne tarpiniame serveryje. Firefox ir Safari tuos pačius keturis gedimus formuluoja kitaip, todėl lyginkite pagal simbolį arba tuščią kūną, o ne pagal tikslią eilutę.
5 žingsnis: pataisykite sluoksnį, į kurį rodo įrodymai
Jei problema yra maršrutizavimas, taisykite užklausą: pataisykite action, neleiskite apdorotojui prasmukti, suderinkite galinį tašką ir metodą ir bandykite dar kartą. Jei problema yra pateikimas, taisykite tai, kas sukūrė kūną, ir išsiaiškinkite, kodėl grąžinamas klaidos dokumentas ten, kur buvo laukiama duomenų. Jei problema yra sutartis, skaitykite tikrąją karkaso laukiamą struktūrą jūsų vykdomai versijai ir formuokite atsakymą pagal ją, o ne atlaisvinkite klientą.
Atsakymas su užblokuota prieiga reikalauja atskiro praėjimo, nes pati užklausa gali būti teisinga, o kūnas gali niekada nepasiekti jūsų kodo. Palyginkite atsakymo Access-Control-Allow-Origin su tiksliu Origin, kurį atsiuntė naršyklė, ir atsiminkite, kad pakaitos simbolis netenkina užklausos su prisijungimo duomenimis. Suderinkite credentials: 'include' kliente su Access-Control-Allow-Credentials: true serveryje ir patikrinkite, ar kvietimas nenaudojo no-cors režimo, kai nepermatomas kūnas yra dokumentuotas rezultatas, o ne defektas.
Pakeisti analizatorių kuo nors atlaidesniu yra vienintelė pataisa, kurios reikėtų vengti. Atsakymo vertinimas kaip kodo arba teksto lupimas, kol jis analizuojamas, paslepia sutarties neatitikimą ir mainais į tylą prideda įterpimo paviršių. Taip pat būtina tikrinti būseną atskirai nuo kūno: 200 su programos lygmens klaidos objektu yra normalus daugelyje API ir turi būti apdorojamas skaitant turinį.
Kai reikia kito žmogaus pagalbos, pasidalykite minimaliu įrašu — metodas, URL, būsena, galutinis URL po peradresavimų, atsakymo turinio tipas, kūno forma ir laukiama sutartis — o ne neapdorotu eksportu. Tinklo archyvuose yra slapukų, žetonų, užklausos eilučių ir asmens duomenų, kurie buvo formoje, o automatinis valytuvas nėra peržiūra.
- Užfiksuokite užklausą be filtro prieš keisdami bet kokį kodą.
- Patvirtinkite, kad iniciatorius buvo jūsų scenarijus, o galutinis URL yra jūsų galinis taškas.
- Klasifikuokite atsakymą prieš liesdami analizatorių.
- Taisykite maršrutizavimą, prieigą, pateikimą arba sutartį ir niekada atlaisvindami analizatoriaus.