Чтение запросов в DevTools
Нажатие кнопки загрузки запускает цепочку действий: форма выбирает тему, JavaScript строит адрес, браузер отправляет запрос, сервер отвечает, а приложение обновляет список. Когда на странице появляется ошибка, важно определить, на каком звене она возникла. Одна красная строка консоли не объясняет всю цепочку.
Продолжим исправленный локальный каталог из lesson-20 архива. Здесь строки длительности уже преобразуются в числа, а API использует только GET и вымышленные данные. Сервер, запросы и измерения ещё не выполнялись; таблицы и ответы ниже описывают договор подготовленного примера.
Запрос появляется после действия
Начальная страница содержит две карточки непосредственно в HTML. При открытии JavaScript не загружает API автоматически. Поэтому сначала откройте Network, убедитесь, что запись включена, очистите видимый журнал и только затем нажмите «Загрузить курсы». Так мы связываем новую запись с конкретным действием формы.
При выбранной теме «Все» ожидается адрес http://127.0.0.1:4310/api/courses?topic=all. В JavaScript он строится через URL и searchParams, а запрос отправляется через fetch. В Network удобно отфильтровать Fetch/XHR, чтобы документ и CSS не смешивались с чтением данных каталога.
const url = new URL("/api/courses", location.origin);
url.searchParams.set("topic", topic);
const response = await fetch(url, {
headers: { Accept: "application/json" }
});
Это фрагмент обработчика формы. Точный origin включает схему, хост и порт. Наша лаборатория использует 127.0.0.1:4310; замена на localhost может изменить условия хранилищ и не должна происходить незаметно во время исследования.
Адрес, инициатор и ответ
Выберите запись API и прочитайте Headers: метод GET, полный адрес, статус и тип содержимого. В нашей модели успешный ответ имеет статус 200 и application/json. В Initiator ожидается ссылка на строку fetch в app.js; она помогает связать сетевое событие с обработчиком, который построил адрес.
Справочник Chrome Network описывает просмотр заголовков, ответа и инициатора. Для нашего урока достаточно нескольких полей: они связывают действие, запрос и данные, не требуя изучать каждую колонку панели одновременно.
Тело ответа содержит объект с массивом courses. Для темы all подготовлены JavaScript и HTML/CSS. У каждого есть id, title, url, topic и строковая длительность minutes. Response показывает данные ответа, а список на странице показывает результат их обработки — это два разных наблюдения.
{"courses":[
{"id":"javascript","title":"JavaScript","url":"/courses/javascript/","topic":"frontend","minutes":"60"},
{"id":"html-css","title":"HTML и CSS","url":"/courses/html-css/","topic":"frontend","minutes":"48"}
]}
Форматирование здесь сделано для чтения; буквальные пробелы сетевого JSON могут отличаться. Существенны структура и значения. Из успешного сетевого статуса ещё не следует, что приложение верно построило все ссылки: это подтверждается отдельно конечными элементами DOM и требованиями модели.
Пустой результат и ошибка параметра
Выберите «Публикация» и снова загрузите данные. Допустимая тема publishing пока не содержит курсов. Ответ должен быть 200 с пустым массивом; интерфейс заменяет список пустым и показывает «Загружено курсов: 0.». Это успешное выполнение запроса, а не ошибка сервера.
Теперь рассмотрим неправильный параметр topic=fronted. Он не входит в допустимые значения. Сервер должен вернуть 400 с application/problem+json и объяснением допустимых тем. Такой запрос можно увидеть в отдельном подготовленном сценарии следующего блока; сейчас он используется как сравнение договора.
| Параметр | Ожидаемый статус | Содержание |
|---|---|---|
| all | 200 | Два курса |
| frontend | 200 | Те же два курса |
| publishing | 200 | Пустой массив |
| fronted | 400 | Problem JSON |
Нельзя оценивать запрос только по наличию карточек. После ошибки обработчик не заменяет старый список: он сохраняет прежние элементы и показывает сообщение. Поэтому видимые две карточки могут относиться к прошлому успешному состоянию, а не к текущему ответу. Полезно читать и статус страницы, и новую сетевую запись.
HTTP-ошибка и отказ сети
fetch обычно возвращает объект ответа и для статуса 400. В нашем коде response.ok явно проверяется, и только затем читается JSON успешного ответа. Следовательно, ошибка параметра превращается в сообщение «Не удалось загрузить: HTTP 400.». Деталь Problem JSON текущий обработчик не показывает, но её можно прочитать в Network.
Описание Fetch API различает получение HTTP-ответа и отклонение запроса. Для примера это важно: выключенный сервер, заблокированный запрос и полученный 400 — разные условия, даже если интерфейс для всех показывает общий текст ошибки.
При настоящем исследовании сначала запишите, есть ли статус HTTP вообще. Если запроса нет в журнале, возможно, запись открыта слишком поздно или форма не дошла до fetch. Если запрос есть, но не получил ответа, исследуется сеть или сервер. Если ответ 200, но список неверный, внимание переносится на структуру данных и обработку DOM.
Для короткого журнала исследования удобно записать последовательность одного действия, а не весь сеанс браузера. Например: открыта лаборатория с выбранным all; запись Network включена до нажатия; отправлен GET с topic=all; договор предусматривает два курса; список должен быть заменён этими двумя карточками. Пока сценарий не выполнен, эта запись остаётся планом наблюдения. После выполнения её можно дополнить фактическим статусом и существенными полями ответа. Такой формат помогает увидеть различие между ожидаемым и полученным без неподтверждённых чисел скорости. Если второе действие относится к publishing, создайте отдельную запись, чтобы не смешивать два ответа с разными условиями.
Кеш и время наблюдения
API нашей лаборатории отвечает с Cache-Control: no-store. CSS, напротив, допускает кеширование на 120 секунд. Поэтому повторная загрузка ресурсов может выглядеть неодинаково. Disable cache в Network используется как условие ручного эксперимента; его состояние нужно записывать и снимать после завершения.
Не превращайте одно локальное время запроса в утверждение о скорости сайта для посетителей. Время зависит от компьютера, состояния браузера, сервера и других условий. В подготовленном материале нет измеренных задержек, размера передачи или результатов оптимизации. Мы учимся читать причину и структуру запроса.
Если сохранить весь журнал без отбора, в нём могут оказаться лишние страницы и данные. Для нашего учебного API это вымышленные значения, но привычка выбирать один нужный запрос полезна и для реального проекта. Метод, адрес, значимые параметры, статус и форма ответа обычно дают понятную первую запись наблюдения.
Конечный результат урока — связь кнопки, инициатора app.js, адреса API и обработанного ответа. Мы различили успешный пустой список, ошибку параметра и отсутствие ответа. В следующем уроке посмотрим, какое состояние браузер хранит между открытиями и почему оно может влиять на воспроизведение.