HTTP (HyperText Transfer Protocol) — протокол для работы с сайтами в браузере.

В его рамках клиент постоянно посылает серверу запросы (request), а сервер на них отвечает (response). Клиент (почти всегда браузер, м.б., робот, который шарится по вебу для поддержания поискового движка) всегда первый отправляет запрос.

Например, когда мы заходим на сайт, браузер делает первый запрос, который влечёт за собой ещё несколько:

GET /

http_response = {
	code: 200,
	body: "<!DOCTYPE ...
		...
			<link rel="stylesheet" href="styles.css">
			<script src="scripts.js"></script>
		...",
	content_type: "text/html"
}
200

⇒ GET /styles.css

⇒ GET /scripts.js

Часть ответа может сохраняться в браузере/в ближайших к браузеру интернет-узлах (напр., у провайдера), т.е. будет происходить кэширование. Какая именно часть должна кэшироваться, указывает сервер в response’е.

Hypertext в названии относится к тому, что в веб-странице содержатся ссылки, переходя по которым пользователь делает новые запросы и получает новые ответы

Есть классификация для статус-кодов ответа:

  1. 1xx — информационные (например, когда сервер долго думает над ответом, он может послать ответ “подождите”, после чего доставить реальный ответ с кодом 2xx или 4xx).
  2. 2xx — успешные (200 — самый популярный)
  3. 3xx — перенаправление (сервер говорит: “у меня нет нужной страницы, но вот тут она есть: …”)
  4. 4xx — ошибка со стороны клиента (ввёл неправильный адрес и получил 404)
  5. 5хх — ошибка со стороны сервера (сервер лежит ⇒ 503)

По http передаётся не только текст. Поддерживаются:

"text/plain", "text/html", "image/gif", "image/jpeg", "audio/mpeg", "video/mpeg", "application/msword", and "application/pdf"

Протокол является stateless, т.е. каждый запрос не знает о существовании предыдущих.

Примерный код для работы выглядит следующим образом:

front:

<form method="POST" action="/orders">
  <input name="order_id" value="123">
  <button type="submit">Place Order</button>
</form>
button.addEventListener('click', () => {
  fetch('/orders', {
    method: 'POST',
    body: JSON.stringify({ order_id: 123 }),
    headers: { 'Content-Type': 'application/json' }
  })
})
POST /orders
Content-Type: application/json

{ "order_id": 123 }

back:

app.post('/orders', (req, res) => {
  const orderId = req.body.order_id
  // save to database, do smt else
  res.send('Order received!')
})

Помимо GET и POST, есть ещё:

HTTP/3: придумали reliable ****протокол QUIC на основе UDP, который стали использовать в качестве основы вместо TCP. Этот протокол решает следующие проблемы:

  1. в TCP 3 подряд идущих файла — это один поток байтов. Если байт первого файла не дошёл, весь поток останавливается. В HTTP/3 если байт одного из файла не дошёл, то два других всё ещё продолжают передаваться.
  2. Меньше времени на рукопожатие: в старой версии сначала производилось TCP-рукопожатие, затем — TLS. QUIC объединяет их в один.
  3. Если произошла смена сокета (напр., клиент перешёл с WiFi на мобильный трафик ⇒ изменился его IP), то раньше соединение разрывалось. Теперь — нет.