HTTP-запрос — это обычное текстовое сообщение определённой формы. Если бы у браузера была кнопка «покажи мне, что ты сейчас отправишь», мы увидели бы что-то такое:
POST /api/posts HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/json
Content-Length: 73
{"title": "Привет, мир", "body": "Это мой первый пост.", "author": "anna"}
В этом примере есть всё, что только может быть у запроса. Разберём по кусочкам.
Стартовая строка: метод + путь + версия
Первая строка — самая важная:
POST /api/posts HTTP/1.1
- Метод — POST. Говорит, что именно мы хотим сделать с ресурсом. Детально про методы — в модуле 3.
- Путь — /api/posts. Адрес ресурса на сервере, без имени домена. Домен лежит ниже, в заголовке Host.
- Версия протокола — HTTP/1.1. Сейчас в индустрии активно используются HTTP/1.1, HTTP/2 и HTTP/3. Для разработки фронтенда разница в основном незаметна.
Заголовки: всё, что не данные
Следом идут заголовки — пары вида Имя: значение, по одной на строку. Их может быть один, может быть тридцать. Каждый несёт какую-то метаинформацию о запросе.
Наиболее частые в работе:
- Host — доменное имя сервера. Браузер ставит его сам, в fetch руками задавать не надо.
- Content-Type — формат данных в теле запроса. Для JSON это application/json, для формы — application/x-www-form-urlencoded или multipart/form-data.
- Accept — формат, в котором мы хотим получить ответ. Сервер видит этот заголовок и решает, в чём отвечать.
- Authorization — токен авторизации, чтобы сервер понимал, от чьего лица запрос. Подробно — в модуле 7.
- User-Agent — идентификатор клиента (название браузера и версия). Браузер опять же ставит сам.
- Cookie — куки, привязанные к этому домену. Браузер прикрепляет автоматически.
Большинство заголовков нам как фронтендерам трогать не нужно — браузер всё расставляет сам. В fetch руками обычно задают только Content-Type, Accept и Authorization.
Пустая строка: разделитель
Между заголовками и телом — обязательная пустая строка. Это сигнал серверу: «заголовки кончились, дальше тело». На взгляд эта деталь незаметна, но без неё сервер не понял бы, где заканчивается метаинформация.
Тело запроса: где едут данные
После пустой строки — тело (body):
{"title": "Привет, мир", "body": "Это мой первый пост.", "author": "anna"}
Тело есть не у всех запросов. Главное правило: у GET и DELETE тела обычно нет. Они должны выражать своё намерение через путь и query-параметры. У POST, PUT, PATCH тело — основной носитель данных.
Формат тела определяется заголовком Content-Type. В REST API почти всегда — JSON. Бывают другие случаи: формы (для загрузки файлов), бинарные данные (например, картинка), текст. О них в модуле 5.
Query-параметры: путь со знаком вопроса
Ещё одно место, где едут данные — query-параметры в самом URL после знака вопроса:
GET /api/posts?author=anna&limit=10&page=2 HTTP/1.1
Это пары «ключ=значение», разделённые амперсандом. Обычно используются для фильтрации, пагинации, поиска — то есть всего, что уточняет «какой именно ресурс или список». Они часть пути запроса и приезжают на сервер вместе со стартовой строкой. Подробно про query-параметры — в главе 5.1.
Что в fetch мы пишем сами
Чтобы заранее настроить ожидания: когда дойдём до fetch в модуле 4, руками нам нужно будет задавать только три вещи — URL (включая query-параметры, если есть), метод и при необходимости заголовки и тело. Всё остальное (Host, User-Agent, Content-Length, Cookie) браузер подставит автоматически.
В следующей главе разберем зеркальную часть — что приходит в ответ.