Formularul este trimis, indicatorul apare, iar consola spune că există un token < neașteptat în JSON la poziția 0. Pagina în sine se încarcă bine, de aceea primul impuls este să dăm vina pe parser sau pe tunel. De obicei niciunul nu este implicat: trimiterea este o cerere diferită de încărcarea paginii, iar ea s-a întors cu ceva ce nu este JSON. Lucrează în ordinea în care browserul chiar dezvăluie asta, pentru că cele patru răspunsuri posibile cer patru remedieri diferite.

Pasul 1: capturează trimiterea care a avut loc cu adevărat

Deschide panoul Rețea înainte de a trimite, setează jurnalul să păstreze intrările între navigări, apoi fă o trimitere de test inofensivă pe un cont pe care ai voie să îl folosești. Selectează cererea inițiată de formularul însuși, nu cererea de document a paginii.

Fii atent la filtre. Un filtru XHR sau Fetch este comod, dar dacă frameworkul încă trimite printr-un iframe ascuns sau un formular creat dinamic, filtrul va ascunde singura cerere care contează. Trimite mai întâi o dată fără filtru și uită-te la ce a apărut.

Pentru cererea aleasă, notează șase lucruri înainte de orice interpretare: metoda, URL-ul complet cu șirul de interogare, statusul, lanțul de redirecționări, Content-Type al răspunsului și primele linii ale corpului. Referința panoului Rețea din Chrome DevTools acoperă vizualizările Headers, Response și Initiator unde se află acestea, iar panourile echivalente din alte browsere arată aceleași câmpuri.

Pasul 2: confirmă că este cererea la care te gândești

Un număr surprinzător de erori JSON sunt de fapt erori de rutare. Dacă handlerul de trimitere aruncă o excepție înainte de a apela preventDefault, browserul face un POST nativ al formularului către adresa din atributul action, iar serverul răspunde cu o pagină HTML completă. Handlerul nu rulează niciodată, deci nu s-a cerut niciodată JSON.

Compară URL-ul din panou cu URL-ul pe care îl apelează JavaScriptul tău. Caută o redirecționare care se termină altundeva, o bară oblică finală lipsă sau în plus, o nepotrivire de metodă în care handlerul trimite GET iar endpointul acceptă POST, sau un formular care trimite către o cale relativă dintr-o pagină care s-a mutat. Urmează lanțul de redirecționări până la capăt și notează URL-ul final, nu primul.

Apoi verifică inițiatorul. Dacă cererea a venit dintr-o navigare de document și nu din scriptul tău, ai găsit deja problema, iar nicio schimbare în parserul răspunsului nu va ajuta.

Pasul 3: clasifică rezultatul în patru categorii

Fiecare rezultat aparține exact uneia dintre ele, iar categoria decide unde te uiți în continuare.

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

Rândurile din mijloc sunt cele diagnosticate greșit, pentru că statusul este 200. O pagină de autentificare atinsă după o redirecționare este un răspuns HTTP perfect bun și un document JSON foarte prost. Tipul de conținut application/json nu repară asta: este o etichetă, iar un corp etichetat greșit tot nu se poate parsa. Acces blocat este rândul care arată ca o cerere finalizată: panoul arată un status, dar politica de origine încrucișată reține corpul, așa că pentru scriptul care apelează este la fel de inutil ca un timeout.

Al patrulea rând este la fel de frecvent pe stivele vechi de PHP și de frameworkuri. Un avertisment de depreciere tipărit înaintea sarcinii codificate produce un corp pe care niciun parser JSON nu îl va accepta, iar adesea acel avertisment este toată explicația.

Pasul 4: citește eroarea parserului literal

Textul erorii numește primul caracter care a rupt parsarea, iar asta identifică de obicei categoria fără nicio presupunere.

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

Un corp gol cu 200 este un caz separat: endpointul a rulat, nu a produs nimic, iar ceva mai jos a tratat asta ca succes. Este o defecțiune de contract a aplicației, nu de transport, și locul ei este în pasul următor, nu în proxy. Firefox și Safari formulează altfel aceleași patru defecțiuni, așa că potrivește după caracter sau după corpul gol, nu după șirul exact.

Pasul 5: repară stratul pe care indică dovezile

Pentru o problemă de rutare, repară cererea: corectează action, împiedică handlerul să cadă, aliniază endpointul și metoda, apoi testează din nou. Pentru o problemă de reprezentare, repară ce a produs corpul și află de ce se întoarce un document de eroare acolo unde se așteptau date. Pentru o problemă de contract, citește structura reală așteptată de framework pentru versiunea pe care o rulezi și modelează răspunsul după ea în loc să slăbești clientul.

Un răspuns cu acces blocat are nevoie de propria trecere, pentru că cererea în sine poate fi corectă, iar corpul poate să nu ajungă niciodată la codul tău. Compară Access-Control-Allow-Origin al răspunsului cu Originul exact trimis de browser și ține minte că un wildcard nu satisface o cerere cu credențiale. Împerechează credentials: 'include' pe client cu Access-Control-Allow-Credentials: true pe server și verifică dacă apelul a folosit modul no-cors, unde un corp opac este rezultatul documentat, nu un defect.

Înlocuirea parserului cu ceva mai îngăduitor este singura remediere de evitat. Evaluarea răspunsului ca cod sau decojirea textului până când se parsează ascunde nepotrivirea de contract și adaugă o suprafață de injecție în schimbul tăcerii. De asemenea, verificarea statusului separat de corp este obligatorie: un 200 care poartă un obiect de eroare la nivel de aplicație este normal în multe API-uri și trebuie tratat citind sarcina.

Când ai nevoie de ajutorul altcuiva, împărtășește o înregistrare minimă — metodă, URL, status, URL final după redirecționări, tipul de conținut al răspunsului, forma corpului și contractul așteptat — în loc de un export brut. Arhivele de rețea conțin cookie-uri, tokenuri, șiruri de interogare și datele personale care erau în formular, iar un curățitor automat nu este o revizuire.

  • Capturează cererea fără filtru înainte de a schimba orice cod.
  • Confirmă că inițiatorul a fost scriptul tău și că URL-ul final este endpointul tău.
  • Clasifică răspunsul înainte de a atinge parserul.
  • Repară rutarea, accesul, reprezentarea sau contractul și niciodată slăbind parserul.

Articole similare