Формулярът се изпраща, появи се индикаторът и конзолата казва неочакван символ < в 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 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

Средните редове са тези, които хората диагностицират погрешно, защото статусът е 200. Страница за вход, достигната след пренасочване, е напълно добър HTTP отговор и много лош JSON документ. Типът на съдържанието application/json не поправя това: той е етикет и неправилно етикетирано тяло пак не се парсва. Достъпът е блокиран е редът, който изглежда завършена заявка: панелът показва статус, но политиката за различни източници задържа тялото, така че за викащия скрипт то е толкова неизползваемо, колкото и изтичане на времето.

Четвъртият ред е също толкова чест при по-стари стекове с PHP и фреймуърци. Предупреждение за отпадане, отпечатано преди кодирания товар, създава тяло, което никой JSON парсер няма да приеме, и предупреждението често е цялото обяснение.

Стъпка 4: четете грешката на парсера буквално

Текстът на грешката назовава първия символ, който е счупил разбора, и това обикновено определя категорията без никакво гадаене.

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

Празното тяло със статус 200 е отделен случай: крайната точка е работила, не е произвела нищо и нещо по-надолу го е приело за успех. Това е отказ на договора на приложението, а не на транспорта, и мястото му е в следващата стъпка, не в проксито. Firefox и Safari формулират същите четири отказа по друг начин, затова сравнявайте по символа или по празното тяло, а не по точния низ.

Стъпка 5: поправете слоя, който доказателствата сочат

При проблем с маршрутизирането поправете заявката: коригирайте action, не позволявайте на обработчика да пропадне, приведете крайната точка и метода в съответствие и тествайте отново. При проблем с представянето поправете това, което е произвело тялото, и разберете защо се връща документ за грешка там, където се очакват данни. При проблем с договора прочетете действителната очаквана структура на фреймуърка за версията, която изпълнявате, и оформете отговора по нея, вместо да разхлабвате клиента.

Отговорът с блокиран достъп изисква отделно минаване, защото самата заявка може да е правилна, а тялото може никога да не стигне до кода ви. Сравнете Access-Control-Allow-Origin на отговора с точния Origin, който браузърът е изпратил, и помнете, че заместващият знак не удовлетворява заявка с идентификационни данни. Свържете credentials: 'include' от страна на клиента с Access-Control-Allow-Credentials: true от страна на сървъра и проверете дали извикването не е използвало режим no-cors, където непрозрачното тяло е документиран резултат, а не дефект.

Замяната на парсера с нещо по-снизходително е единствената поправка, която трябва да се избягва. Изпълняването на отговора като код или отстраняването на текст, докато се парсне, скрива несъответствието в договора и добавя повърхност за инжектиране в замяна на тишина. Също така проверката на статуса отделно от тялото е задължителна: статус 200 с обект за грешка на ниво приложение е нормален в много API и трябва да се обработва чрез четене на товара.

Когато ви трябва помощ от някого, споделете минимален запис — метод, URL, статус, краен URL след пренасочванията, тип на съдържанието на отговора, форма на тялото и очаквания договор — вместо суров експорт. Архивите на мрежата съдържат бисквитки, токени, низове на заявката и личните данни, които са били във формуляра, а автоматичният изчистващ инструмент не е преглед.

  • Уловете заявката без филтър, преди да промените какъвто и да е код.
  • Потвърдете, че инициаторът е бил вашият скрипт, а крайният URL е вашата крайна точка.
  • Класифицирайте отговора, преди да пипате парсера.
  • Поправете маршрутизирането, достъпа, представянето или договора и никога чрез разхлабване на парсера.

Подобни статии