ДокументацияОсновы вебаHTTP/HTTPS: методы, статус-коды, заголовки
Начальный 15 мин чтения

HTTP/HTTPS: методы, статус-коды, заголовки

Протокол HTTP для фронтендера: методы GET, POST, PUT, DELETE, PATCH, статус-коды, заголовки, HTTPS, HTTP/2 и HTTP/3, кэширование.

httphttpsreststatus-codesheadersnetwork

Что такое HTTP

HTTP (HyperText Transfer Protocol) — протокол передачи данных, на котором работает весь веб. Когда вы открываете сайт, браузер отправляет HTTP-запрос на сервер, а сервер возвращает HTTP-ответ.

Каждый HTTP-обмен состоит из двух частей:

  1. Запрос (Request) — от клиента (браузера) к серверу
  2. Ответ (Response) — от сервера к клиенту
Клиент (браузер)                    Сервер
    │                                  │
    │  GET /users HTTP/1.1             │
    │  Host: api.example.com           │
    │  ──────────────────────────────► │
    │                                  │
    │  HTTP/1.1 200 OK                 │
    │  Content-Type: application/json  │
    │  ◄────────────────────────────── │
    │                                  │

Структура HTTP-запроса

GET /api/users?page=1&limit=10 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGci...
Content-Type: application/json
Accept: application/json

Части запроса:

  • МетодGET
  • URL/api/users?page=1&limit=10
  • Версия протоколаHTTP/1.1
  • Заголовки — метаданные (Host, Authorization, Content-Type)
  • Тело — данные (у GET тела нет, у POST — JSON)

HTTP-методы

Метод указывает, какое действие нужно выполнить с ресурсом.

GET — получить данные

const response = await fetch('/api/users?page=1')
const users = await response.json()

Особенности:

  • Не имеет тела запроса
  • Параметры передаются в URL (query string)
  • Безопасный — не меняет данные на сервере
  • Идемпотентный — повторный запрос даёт тот же результат
  • Можно кэшировать

POST — создать данные

const response = await fetch('/api/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Анна', email: 'anna@example.com' }),
})
const newUser = await response.json()

Особенности:

  • Имеет тело запроса (JSON, form-data, plain text)
  • Не идемпотентный — два POST создадут две записи
  • Не кэшируется

PUT — заменить данные целиком

const response = await fetch('/api/users/1', {
  method: 'PUT',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Анна Иванова', email: 'anna@new.com', age: 25 }),
})

Особенности:

  • Заменяет ресурс целиком (все поля)
  • Идемпотентный — повторный PUT с теми же данными не меняет состояние

PATCH — частичное обновление

const response = await fetch('/api/users/1', {
  method: 'PATCH',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'anna@new.com' }),
})

Особенности:

  • Обновляет только переданные поля
  • Часто используется вместо PUT

DELETE — удалить данные

await fetch('/api/users/1', { method: 'DELETE' })

Идемпотентный — удаление уже удалённого ресурса возвращает 404, но состояние не меняется.

Сравнение методов

МетодДействиеТело запросаИдемпотентныйБезопасный
GETПолучитьНетДаДа
POSTСоздатьДаНетНет
PUTЗаменитьДаДаНет
PATCHОбновить частичноДаНет*Нет
DELETEУдалитьНет/ДаДаНет

* PATCH теоретически не идемпотентный, но на практике часто реализуют как идемпотентный.

Другие методы

  • HEAD — как GET, но без тела ответа (только заголовки). Проверить существует ли ресурс
  • OPTIONS — какие методы поддерживаются (используется в CORS preflight)
  • TRACE — диагностический (обычно отключен на серверах)

Статус-коды

Статус-код — трёхзначное число в ответе сервера. Показывает результат обработки запроса.

1xx — Informational

Редко встречаются. 100 Continue — сервер готов принять тело запроса.

2xx — Success

КодЗначениеКогда использовать
200OKУспешный GET, PUT, PATCH
201CreatedУспешный POST (ресурс создан)
204No ContentУспешный DELETE (нет тела ответа)
206Partial ContentЧастичное содержимое (Range-запросы)

3xx — Redirection

КодЗначениеКогда использовать
301Moved PermanentlyРесурс навсегда перемещён (SEO-редирект)
302FoundВременный редирект
304Not ModifiedКэш валиден, не нужно скачивать снова
307Temporary RedirectВременный редирект (сохраняет метод)
308Permanent RedirectПостоянный редирект (сохраняет метод)

4xx — Client Error

КодЗначениеПричина
400Bad RequestНеверный формат запроса
401UnauthorizedНе авторизован (нет токена)
403ForbiddenНет прав доступа
404Not FoundРесурс не найден
405Method Not AllowedМетод не поддерживается
408Request TimeoutТаймаут запроса
409ConflictКонфликт (дубликат email)
422Unprocessable EntityОшибка валидации данных
429Too Many RequestsПревышен лимит запросов (rate limit)

5xx — Server Error

КодЗначениеПричина
500Internal Server ErrorОшибка на сервере
502Bad GatewayСервер-посредник получил неверный ответ
503Service UnavailableСервер перегружен / на обслуживании
504Gateway TimeoutТаймаут при обращении к другому серверу

Как обрабатывать статус-коды

async function fetchUsers() {
  const response = await fetch('/api/users')

  if (!response.ok) {
    switch (response.status) {
      case 401:
        throw new Error('Необходима авторизация')
      case 403:
        throw new Error('Нет доступа')
      case 404:
        throw new Error('Пользователи не найдены')
      case 429:
        throw new Error('Слишком много запросов')
      default:
        throw new Error(`Ошибка сервера: ${response.status}`)
    }
  }

  return response.json()
}

HTTP-заголовки

Заголовки — метаданные запроса и ответа. Формат: Имя: Значение.

Заголовки запроса (Request Headers)

ЗаголовокОписаниеПример
HostДомен сервераapi.example.com
User-AgentИнформация о клиентеMozilla/5.0 (Macintosh; ...)
AcceptОжидаемый формат ответаapplication/json
Content-TypeФормат тела запросаapplication/json
AuthorizationДанные авторизацииBearer eyJhbGci...
CookieКуки для доменаsession_id=abc123
RefererURL предыдущей страницыhttps://example.com/page
OriginИсточник запроса (для CORS)https://example.com
Cache-ControlНастройки кэшированияno-cache
If-None-MatchУсловный запрос (ETag)"abc123"

Заголовки ответа (Response Headers)

ЗаголовокОписаниеПример
Content-TypeФормат тела ответаapplication/json; charset=utf-8
Content-LengthРазмер тела в байтах1234
Set-CookieУстановить кукуsession=abc; HttpOnly; Secure
Cache-ControlКак кэшироватьmax-age=3600, public
ETagИдентификатор версии"abc123"
LocationURL для редиректаhttps://example.com/new
Access-Control-Allow-OriginCORShttps://example.com
X-Request-IdИдентификатор запросаreq-abc-123
Content-Security-PolicyCSPdefault-src 'self'
Strict-Transport-SecurityHSTSmax-age=31536000

Content-Type — типы содержимого

application/json                      → JSON
application/x-www-form-urlencoded     → Форма (default HTML form)
multipart/form-data                   → Загрузка файлов
text/html                             → HTML
text/css                              → CSS
text/plain                            → Простой текст
application/xml                       → XML
application/octet-stream              → Бинарные данные

HTTPS

HTTPS = HTTP + TLS (шифрование). Данные между браузером и сервером зашифрованы — злоумышленник не может перехватить пароли и токены.

Как работает TLS

  1. Браузер подключается к серверу по порту 443
  2. TLS-handshake: обмен ключами, проверка сертификата
  3. Устанавливается зашифрованное соединение
  4. Данные передаются в зашифрованном виде

Сертификаты

SSL/TLS-сертификат подтверждает, что сервер — тот, за кого себя выдаёт. Выпускается Certificate Authority (CA):

  • Let's Encrypt — бесплатный, автоматический
  • Cloudflare — бесплатный с CDN
  • Платные: DigiCert, Sectigo, GlobalSign

Сегодня все сайты должны использовать HTTPS. Google помечает HTTP-сайты как «Не защищено» и понижает их в поисковой выдаче.

HTTP/2 и HTTP/3

HTTP/1.1

  • Один запрос за раз на одно TCP-соединение (или 6 параллельных)
  • Заголовки передаются как текст (избыточно)
  • Head-of-line blocking — медленный запрос блокирует последующие

HTTP/2

  • Multiplexing — множество запросов по одному соединению
  • Бинарный протокол — эффективнее текстового
  • Сжатие заголовков (HPACK)
  • Server Push — сервер может отправить ресурсы проактивно
  • Приоритизация — важные ресурсы загружаются первыми

Поддерживается всеми современными браузерами. Nginx и Cloudflare включают HTTP/2 по умолчанию.

HTTP/3 (QUIC)

  • На базе UDP вместо TCP
  • Нет head-of-line blocking на уровне транспорта
  • Быстрое установление соединения (0-RTT)
  • Лучшая работа при потере пакетов

Google, Cloudflare и Facebook уже используют HTTP/3.

Кэширование

Cache-Control

Cache-Control: max-age=3600, public          # Кэшировать на 1 час
Cache-Control: no-cache                       # Всегда проверять (revalidate)
Cache-Control: no-store                       # Не кэшировать вообще
Cache-Control: private                        # Только для одного пользователя
Cache-Control: public                         # Для всех (CDN тоже)

ETag

Сервер возвращает ETag: "abc123". При следующем запросе браузер отправляет If-None-Match: "abc123". Если данные не изменились, сервер возвращает 304 Not Modified без тела — экономит трафик.

Last-Modified

Аналогично ETag, но по дате:

Last-Modified: Mon, 15 Jan 2025 10:00:00 GMT
If-Modified-Since: Mon, 15 Jan 2025 10:00:00 GMT

Паттерн кэширования фронтендера

const response = await fetch('/api/users', {
  headers: {
    'If-None-Match': cachedETag,
  },
})

if (response.status === 304) {
  return cachedData
}

const etag = response.headers.get('ETag')
const data = await response.json()
cache.set('users', { data, etag })
return data

Практические советы

Всегда обрабатывайте ошибки

try {
  const response = await fetch('/api/users')
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`)
  }
  return await response.json()
} catch (error) {
  if (error instanceof TypeError) {
    // Сеть недоступна
  }
  throw error
}

Timeout для fetch

const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), 5000)

try {
  const response = await fetch('/api/users', { signal: controller.signal })
  const data = await response.json()
  return data
} catch (error) {
  if (error.name === 'AbortError') {
    throw new Error('Запрос превысил таймаут 5 секунд')
  }
  throw error
} finally {
  clearTimeout(timeout)
}

Итог

  • HTTP — протокол запрос-ответ, основа веба
  • 5 основных методов: GET (получить), POST (создать), PUT (заменить), PATCH (обновить), DELETE (удалить)
  • Статус-коды: 2xx — успех, 3xx — редирект, 4xx — ошибка клиента, 5xx — ошибка сервера
  • HTTPS обязателен — шифрование данных через TLS
  • HTTP/2 — multiplexing, сжатие заголовков, быстрее HTTP/1.1
  • Кэширование через Cache-Control, ETag, Last-Modified экономит трафик и ускоряет загрузку