AJAX ფორმა JSON-ს ელოდება, მაგრამ HTML-ს იღებს: გააანალიზეთ პასუხი ეტაპობრივად
200 სტატუსი JSON-ის მტკიცებულება არ არის. გაიარეთ Network პანელი ეტაპობრივად და გამოყავით ტრანსპორტის, წარდგენისა და კონტრაქტის ჩავარდნები.
ფორმა იგზავნება, სპინერი ჩნდება და კონსოლი ამბობს, რომ JSON-ში 0 პოზიციაზე მოულოდნელი სიმბოლო < არის. გვერდი თავად კარგად იტვირთება, ამიტომ პირველი ინსტინქტი პარსერს ან გვირაბს დაადანაშაულოს. ჩვეულებრივ არც ერთი მონაწილეობს: გაგზავნა გვერდის ჩატვირთვისგან განსხვავებული მოთხოვნაა და ის დაბრუნდა იმით, რაც JSON არ არის. იმუშავეთ იმ თანმიმდევრობით, რომლითაც ბრაუზერი რეალურად ავლენს ამას, რადგან ოთხი შესაძლო პასუხი ოთხ სხვადასხვა შესწორებას მოითხოვს.
ეტაპი 1: დაიჭირეთ გაგზავნა, რომელიც ნამდვილად მოხდა
გახსენით Network პანელი გაგზავნამდე, დააყენეთ ჟურნალი ისე, რომ ჩანაწერები ნავიგაციებს შორის შენარჩუნდეს, შემდეგ კეთებით ერთი უვნებელი საცდელი გაგზავნა იმ ანგარიშზე, რომლის გამოყენების უფლებაც გაქვთ. აირჩიეთ მოთხოვნა, რომელიც თავად ფორმამ დაიწყო და არა გვერდის დოკუმენტის მოთხოვნა.
ფილტრებთან ფრთხილად იყავით. XHR ან Fetch ფილტრი მოსახერხებელია, მაგრამ თუ ჩარჩო ჯერ კიდევ ფარული iframe-ით ან დინამიკურად შექმნილი ფორმით აგზავნის, ფილტრი დამალავს ერთადერთ მნიშვნელოვან მოთხოვნას. ჯერ ერთხელ გაგზავნეთ ფილტრის გარეშე და ნახეთ რა გამოჩნდა.
არჩეული მოთხოვნისთვის, ნებისმიერი ინტერპრეტაციის წინ, ჩაწერეთ ექვსი რამ: მეთოდი, სრული URL მოთხოვნის სტრიქონით, სტატუსი, გადამისამართების ჯაჭვი, პასუხის Content-Type და სხეულის პირველი სტრიქონები. Chrome DevTools-ის Network პანელის სახელმძღვანელო მოიცავს 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 გადამისამართებების შემდეგ, პასუხის შიგთავსის ტიპი, სხეულის ფორმა და მოსალოდნელი კონტრაქტი — და არა ნედლი ექსპორტი. ქსელურ არქივებში არის cookie-ები, ტოკენები, მოთხოვნის სტრიქონები და ფორმაში არსებული პირადი მონაცემები, ხოლო ავტომატური გამწმენდი განხილვა არ არის.
- დაიჭირეთ მოთხოვნა ფილტრის გარეშე სანამ რომელიმე კოდს შეცვლით.
- დარწმუნდით, რომ ინიციატორი თქვენი სკრიპტი იყო და საბოლოო URL თქვენი საბოლოო წერტილია.
- დაალაგეთ პასუხი სანამ პარსერს შეეხებით.
- შეასწორეთ მარშრუტიზაცია, წვდომა, წარდგენა ან კონტრაქტი და არასდროს პარსერის შესუსტებით.