HTTP (HyperText Transfer Protocol) - это прикладной протокол передачи данных, который лежит в основе Всемирной паутины (World Wide Web). Именно благодаря HTTP браузеры, мобильные приложения, серверы, микросервисы и API могут обмениваться информацией друг с другом.

Когда вы открываете любой сайт, например, https://google.com, происходит HTTP-запрос к серверу Google, а сервер отправляет HTTP-ответ с HTML-страницей, изображениями, JavaScript-файлами и другими ресурсами.

Несмотря на название HyperText, сегодня HTTP используется далеко не только для передачи HTML-документов. Через него передаются: HTML, CSS, JavaScript, JSON, XML, изображения, видео, аудио, PDF, архивы, файлы любого типа.

Сегодня практически любое REST API построено именно поверх HTTP.

HTTP работает по модели Request & Response.

Любое взаимодействие состоит из двух сообщений:

  • HTTP Request
  • HTTP Response

HTTP/0.9 (1991)

Самая первая версия.

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

  • только GET
  • только HTML
  • отсутствовали заголовки
  • отсутствовал статус ответа

Пример:

GET /index.html

Ответ:

<html>...</html>

HTTP/1.0 (1996)

Добавились:

  • заголовки
  • статус-коды
  • различные типы контента
  • POST
  • MIME-типы

Каждый запрос открывал новое TCP-соединение. Это было очень медленно.


HTTP/1.1 (1997)

Самая распространенная версия за последние 20 лет.

Появились:

  • Keep-Alive
  • Host Header
  • Chunked Transfer Encoding
  • кэширование
  • новые методы
  • улучшенное управление соединением

Главное отличие:

TCP соединение теперь можно было не закрывать после каждого запроса. Это значительно ускорило работу сайтов.


HTTP/2 (2015)

Основные проблемы HTTP/1.1:

  • Head of Line Blocking
  • множество TCP соединений
  • текстовый формат

HTTP/2 решил их.

Появились:

  • Binary Protocol

Вместо текста используется бинарный формат.

- Multiplexing

Несколько запросов могут одновременно идти внутри одного TCP соединения.

Теперь браузеру не нужно ждать окончания предыдущего запроса.

- Header Compression

Используется алгоритм HPACK. Это уменьшает объем передаваемых заголовков.


HTTP/3 (2022)

Главное изменение - HTTP больше не использует TCP. Теперь используется QUIC.

Преимущества:

  • быстрее установка соединения
  • меньше задержки
  • отсутствие TCP Head-of-Line Blocking
  • лучше работает при потере пакетов
  • быстрее переключается между Wi-Fi и мобильной сетью

HTTP/3 становится новым стандартом Интернета.


Формат URL

Любой HTTP-запрос отправляется на определенный URL.

Например:

https://api.example.com:443/v1/users/25?sort=name#profile

Разберем его по частям.

Scheme

https

Определяет используемый протокол.

Возможные варианты:

  • http
  • https
  • ftp
  • ws
  • wss

Host

api.example.com

Домен сервера.

Port

443

Порт сервера.

Стандартные:

  • 80
  • 443

Path

/v1/users/25

Путь к ресурсу.

Query Parameters

?sort=name&page=2

Передают дополнительные параметры.

Fragment

#profile

Используется браузером для перехода к определенной части документа и не отправляется на сервер.


Клиент-серверная архитектура

HTTP построен по модели Client-Server.

HTTP Request

Каждый запрос состоит из нескольких частей.

GET /users?page=1 HTTP/1.1

Host: api.example.com
Accept: application/json
Authorization: Bearer token
User-Agent: Chrome

(Body)

- Request Line

GET /users HTTP/1.1

Содержит:

  • метод
  • путь
  • версию HTTP

- Headers

Заголовки содержат дополнительную информацию.

Например:

  • Host
  • Authorization
  • Accept
  • Content-Type
  • Cookie
  • User-Agent
  • Accept-Language
  • Accept-Encoding
  • Referer
  • Origin
  • Cache-Control
  • If-None-Match
  • If-Modified-Since

- Body

Тело присутствует не всегда.

Обычно используется в:

  • POST
  • PUT
  • PATCH

HTTP Response

Ответ также состоит из нескольких частей.

HTTP/1.1 200 OK

Content-Type: application/json
Content-Length: 120
Cache-Control: no-cache

{
    ...
}

- Status Line

HTTP/1.1 200 OK

Содержит:

  • версию
  • статус-код
  • текстовое описание

- Headers

Часто используются:

  • Content-Type
  • Content-Length
  • Date
  • ETag
  • Set-Cookie
  • Cache-Control
  • Server
  • Location
  • Last-Modified

- Response Body

Может содержать: HTML, JSON, XML, изображение, PDF, видео, файл.


HTTP Status Codes

Все статусы делятся на 5 категорий.

  • 1xx Informational
  • 2xx Success
  • 3xx Redirection
  • 4xx Client Error
  • 5xx Server Error

HTTP Методы

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE
  • HEAD
  • OPTIONS
  • TRACE
  • CONNECT

GET

Получение данных.

GET /users

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

  • безопасный (Safe)
  • идемпотентный (Idempotent)
  • может кешироваться
  • тело запроса обычно отсутствует (стандарт не запрещает тело, но большинство серверов и клиентов его игнорируют)

POST

Создание ресурса.

POST /users

{
 "name":"Alex"
}

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

  • не Safe
  • не идемпотентный
  • обычно используется для создания

PUT

Полная замена ресурса.

PUT /users/5

{
 "name":"Alex",
 "age":30
}

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

  • идемпотентный
  • заменяет ресурс полностью

PATCH

Частичное обновление.

PATCH /users/5

{
 "age":31
}

Обновляет только указанные поля.


DELETE

DELETE /users/5

Идемпотентный метод: повторный DELETE не должен изменять результат после успешного удаления (хотя ответы могут различаться, например, сначала 204, затем 404).


HEAD

Возвращает только заголовки.

HEAD /image.png

Используется для:

  • проверки существования
  • получения размера
  • проверки кеша

OPTIONS

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

Ответ может содержать:

Allow:
GET
POST
DELETE

Также активно используется браузерами при CORS Preflight запросах.


TRACE

Возвращает запрос обратно клиенту.

Используется для:

  • диагностики
  • отладки

Часто отключается на серверах из соображений безопасности.


CONNECT

Создает TCP-туннель через HTTP-прокси.

Используется HTTPS-прокси для организации защищенных соединений.


Safe и Idempotent методы

Safe означает, что метод не должен изменять состояние сервера.

Idempotent означает, что многократное выполнение одинакового запроса приводит к тому же конечному состоянию ресурса, что и однократное выполнение.


Кэширование

Кэширование позволяет уменьшить количество запросов к серверу, сократить задержку и снизить нагрузку на инфраструктуру.

Cache-Control

Наиболее важный заголовок.

Cache-Control:
max-age=3600

Ответ можно хранить один час.

Cache-Control:
no-cache

Перед использованием закэшированной копии клиент обязан проверить её актуальность у сервера.

Cache-Control:
no-store

Вообще запрещает сохранять ответ.

Cache-Control:
public

Можно закэшировать в любых кэшах (хранилище).

Cache-Control:
private

Только в браузере пользователя.

ETag

Сервер возвращает уникальный идентификатор версии ресурса.

ETag:
"a8d92f"

Last-Modified

Last-Modified:
Wed, 12 Jun 2024 12:00:00 GMT

Cookies

HTTP является stateless-протоколом, поэтому для сохранения состояния часто используются Cookies.

Сервер отправляет:

Set-Cookie:
session=abc123;
HttpOnly;
Secure;
SameSite=Lax

Браузер автоматически отправляет:

Cookie:
session=abc123

Флаги:

  • HttpOnly - запрещает доступ к Cookies из JavaScript.
  • Secure - передавать Cookies только по HTTPS.
  • SameSite (Strict, Lax, None) - ограничивает отправку Cookies в межсайтовых запросах и помогает защититься от CSRF.

Stateless

Одно из важнейших свойств HTTP - Stateless Protocol.

Сервер не хранит информацию о предыдущих запросах между разными HTTP-запросами по умолчанию.

Каждый запрос является полностью самостоятельным.

Если необходимо знать, что оба запроса принадлежат одному пользователю, приложение должно самостоятельно передать контекст, например:

  • Cookies
  • Session ID
  • JWT
  • OAuth Access Token
  • API Key

Статус соединения TCP или HTTP не заменяет состояние приложения.


HTTPS и HTTP

Важно понимать разницу между HTTP и HTTPS.

HTTP передает данные в открытом виде.

HTTPS (HTTP Secure) - это HTTP, работающий поверх TLS (Transport Layer Security), который обеспечивает:

  • шифрование передаваемых данных;
  • проверку подлинности сервера с помощью сертификатов;
  • защиту от изменения данных во время передачи (целостность).

Сегодня практически все современные сайты используют HTTPS по умолчанию.


Source: Orkhan Alishov's notes