AJAX форма очекува JSON, но добива HTML: прегледајте одговорот чекор по чекор
Одговор со статус 200 не е доказ дека е JSON. Поминете низ панелот Мрежа чекор по чекор и разделете ги дефектите во преносот, приказот и договорот.
Формата се испраќа, покажувачот се појавува и конзолата вели дека има неочекуван знак < во JSON на позиција 0. Самата страница се вчитува добро, затоа првиот импулс е да се обвини парсерот или тунелот. Обично ниту еден не учествува: испраќањето е друг барање од вчитувањето на страницата, и се врати со нешто што не е JSON. Работете по редоследот по кој прелистувачот навистина го открива тоа, бидејќи четирите можни одговори бараат четири различни поправки.
Чекор 1: фатете го испраќањето што навистина се случи
Отворете го панелот Мрежа пред да испратите, поставете го дневникот да ги чува записите низ навигациите, па направете едно безопасно пробно испраќање на сметка што смеете да ја користите. Изберете го барањето што го започна самата форма, а не барањето на документот на страницата.
Внимавајте со филтрите. Филтер XHR или Fetch е удобен, но ако рамката сè уште испраќа преку скриен iframe или динамично создадена форма, филтерот ќе го скрие единственото важно барање. Прво испратете еднаш без филтер и видете што се појави.
За избраното барање запишете шест работи пред какво било толкување: методот, целосниот URL заедно со низата за барање, статусот, синџирот пренасочувања, Content-Type на одговорот и првите редови од телото. Упатството за панелот Мрежа на Chrome DevTools ги покрива приказите Headers, Response и Initiator каде што се наоѓаат тие, а еквивалентните панели во другите прелистувачи ги прикажуваат истите полиња.
Чекор 2: потврдете дека тоа е барањето што мислите
Зачудувачки многу грешки со JSON се всушност грешки во рутирањето. Ако ракувачот со испраќањето фрли исклучок пред да го повика preventDefault, прелистувачот извршува нативен POST на формата на адресата што ја вели атрибутот action, а серверот одговара со целосна HTML страница. Ракувачот никогаш не се извршува, така што JSON никогаш не бил побарано.
Споредете го URL-то во панелот со URL-то што го повикува вашиот JavaScript. Барајте пренасочување што завршува на друго место, коса црта на крајот што недостига или е вишок, несовпаѓање на методот кога ракувачот испраќа GET, а крајната точка прима POST, или форма што испраќа на релативна патека од страница што се преместила. Следете го синџирот пренасочувања до крајот и запишете го конечниот URL, не првиот.
Потоа проверете го иницијаторот. Ако барањето дојде од навигација на документ, а не од вашата скрипта, проблемот веќе го најдовте, и никаква промена во парсерот на одговор нема да помогне.
Чекор 3: разврстете го резултатот во четири категории
Секој резултат припаѓа точно на една од нив, а категоријата одлучува каде да гледате понатаму.
| 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 |
Средните редови се тие што луѓето ги дијагностицираат погрешно, бидејќи статусот е 200. Страницата за најава до која се доаѓа по пренасочување е сосема добар HTTP одговор и многу лош JSON документ. Типот на содржина application/json тоа не го поправа: тоа е ознака, а погрешно означеното тело сè уште не може да се парсира. Пристапот блокиран е редот што изгледа како завршено барање: панелот покажува статус, но политиката за вкрстено потекло го задржува телото, па за скриптата што повикува тоа е исто толку неупотребливо како истекот на време.
Четвртиот ред е исто толку чест на постари PHP и рамковни стекови. Предупредувањето за застареност испечатено пред кодираниот товар создава тело што ниту еден JSON парсер нема да го прифати, и често тоа предупредување е целото објаснување.
Чекор 4: прочитајте ја грешката на парсерот буквално
Текстот на грешката го именува првиот знак што го скрши парсирањето, и тоа обично ја идентификува категоријата без никакво погодување.
| 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 |
Празно тело со 200 е посебен случај: крајната точка работеше, не произведе ништо, а нешто подолу го зеде тоа како успех. Тоа е дефект во договорот на апликацијата, а не во преносот, и неговото место е во следниот чекор, не во проксито. Firefox и Safari ги формулираат истите четири дефекти поинаку, затоа споредувајте по знакот или по празното тело, а не по точната низа.
Чекор 5: поправете го слојот кон кој упатуваат доказите
За проблем со рутирањето поправете го барањето: исправете го action, спречете ракувачот да пропадне, усогласете крајната точка и методот и тестирајте повторно. За проблем со приказот поправете го тоа што го создаде телото и откријте зошто се враќа документ за грешка таму каде што се очекуваа податоци. За проблем со договорот прочитајте ја вистинската очекувана структура на рамката за верзијата што ја извршувате и обликувајте го одговорот според неа наместо да го олабавите клиентот.
Одговорот со блокиран пристап бара свој премин, бидејќи самото барање може да биде точно, а телото може никогаш да не стигне до вашиот код. Споредете го Access-Control-Allow-Origin на одговорот со точното Origin што го испратил прелистувачот и запомнете дека џокерот не задоволува барање со акредитиви. Спарете го credentials: 'include' на клиентот со Access-Control-Allow-Credentials: true на серверот и проверете дали повикувањето го користело режимот no-cors, каде непровирното тело е документиран резултат, а не дефект.
Замената на парсерот со нешто попопустливо е единствената поправка што треба да се избегне. Оценувањето на одговорот како код или лупењето текст додека не се парсира ја крие неусогласеноста на договорот и додава површина за инјектирање за возврат на тишината. Исто така, проверката на статусот одделно од телото е задолжителна: 200 со објект за грешка на ниво на апликација е нормално во многу API и мора да се обработи со читање на товарот.
Кога ви треба помош од некој друг, споделете минимален запис — метод, URL, статус, конечен URL по пренасочувањата, тип на содржина на одговорот, форма на телото и очекуваниот договор — наместо суров извоз. Мрежните архиви содржат колачиња, токени, низи за барање и личните податоци што биле во формата, а автоматскиот чистач не е преглед.
- Фатете го барањето без филтер пред да смените каков било код.
- Потврдете дека иницијаторот била вашата скрипта и дека конечниот URL е вашата крајна точка.
- Класифицирајте го одговорот пред да го допрете парсерот.
- Поправете рутирање, пристап, приказ или договор и никогаш со олабавување на парсерот.