Пошук уроків, статей та іншого контенту
Розберете життєвий цикл HTTP-запиту між браузером і сервером та роль запиту, відповіді й протоколу.
Коли браузер відкриває сторінку або JavaScript отримує дані із сервера, між ними відбувається обмін повідомленнями.
Цей обмін відбувається за протоколом HTTP — набором правил, які описують:
як браузер має сформувати запит;
як сервер має на нього відповісти;
у якому форматі передаються дані;
як повідомити про успіх або помилку.
Учасники обміну:
клієнт — зазвичай браузер;
сервер — комп’ютер або програма, яка приймає запити й повертає відповіді;
HTTP — протокол взаємодії між ними.
Спрощено життєвий цикл виглядає так:
Браузер → HTTP-запит → Сервер
Браузер ← HTTP-відповідь ← СерверЗапит може виникнути в різних ситуаціях:
користувач вводить адресу в адресний рядок;
користувач натискає посилання;
браузер завантажує зображення або CSS-файл;
JavaScript викликає fetch;
форма надсилає дані на сервер.
Наприклад, користувач відкриває:
https://example.com/productsБраузер розуміє, що потрібно отримати ресурс /products із сервера example.com.
Доменне ім’я зручне для людей, але мережі потрібна IP-адреса сервера.
DNS — це система, яка перетворює доменне ім’я на IP-адресу:
example.com → IP-адреса сервераБраузер може використати вже збережений результат DNS-кешу. Якщо потрібної адреси немає в кеші, він звертається до DNS-сервера.
Після визначення IP-адреси браузер встановлює мережеве з’єднання із сервером.
Для HTTPS додатково виконується TLS-узгодження. Воно потрібне, щоб:
зашифрувати дані;
перевірити сертифікат сервера;
захистити інформацію від перехоплення та зміни.
Різниця між протоколами:
http:// — дані передаються без шифрування;
https:// — HTTP працює поверх захищеного TLS-з’єднання.
На практиці слід використовувати HTTPS.
HTTP-запит складається з кількох частин:
методу;
шляху до ресурсу;
заголовків;
тіла запиту, якщо воно потрібне.
Приклад запиту:
GET /products HTTP/1.1
Host: example.com
Accept: text/html
Accept-Language: ukУ цьому прикладі:
GET — метод запиту;
/products — шлях до ресурсу;
HTTP/1.1 — версія протоколу;
Host — домен сервера;
Accept — типи даних, які браузер може прийняти;
Accept-Language — бажана мова відповіді.
Сервер може:
перевірити метод і адресу;
перевірити права доступу;
звернутися до бази даних;
виконати програмний код;
сформувати HTML, JSON або інший ресурс;
повернути помилку.
Наприклад, для запиту до /products сервер може отримати список товарів із бази даних і сформувати JSON-відповідь.
Час обробки залежить від складності операції. Простий запит до кешованого ресурсу може оброблятися дуже швидко, а запит зі складними обчисленнями — довше.
HTTP-відповідь також має кілька частин:
код стану;
заголовки;
тіло відповіді.
Приклад:
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 42
{"name":"Notebook","price":1000}У цьому прикладі:
200 OK означає успішне виконання запиту;
Content-Type повідомляє формат даних;
тіло містить JSON.
Подальші дії браузера залежать від типу ресурсу:
HTML перетворюється на структуру сторінки;
CSS використовується для оформлення;
JavaScript завантажується та виконується;
зображення декодуються та відображаються;
JSON передається JavaScript-коду.
Під час завантаження HTML браузер може створити багато додаткових запитів:
HTML → запит до CSS
HTML → запит до JavaScript
HTML → запит до зображення
HTML → запит до шрифтуТому одна вебсторінка зазвичай складається не з одного HTTP-запиту, а з багатьох.
Метод описує, яку дію клієнт хоче виконати.
GETОтримання даних.
GET /users/15 HTTP/1.1
Host: example.comGET зазвичай не використовують для зміни даних на сервері.
POSTНадсилання даних для створення ресурсу або виконання операції.
POST /users HTTP/1.1
Host: example.com
Content-Type: application/json
{"name":"Olena","email":"olena@example.com"}PUTПовна заміна наявного ресурсу.
PUT /users/15 HTTP/1.1
Host: example.com
Content-Type: application/json
{"name":"Olena","email":"new@example.com"}PATCHЧасткова зміна ресурсу.
PATCH /users/15 HTTP/1.1
Host: example.com
Content-Type: application/json
{"email":"new@example.com"}DELETEВидалення ресурсу.
DELETE /users/15 HTTP/1.1
Host: example.comУ реальних API правила використання методів визначає конкретний сервер.
Заголовки передають додаткову інформацію про запит або відповідь.
Поширені заголовки запиту:
Host — домен сервера;
Accept — формати, які клієнт може обробити;
Content-Type — формат тіла запиту;
Authorization — дані для автентифікації;
Cookie — збережені дані сесії;
Cache-Control — правила кешування.
Поширені заголовки відповіді:
Content-Type — формат відповіді;
Content-Length — розмір тіла;
Set-Cookie — команда зберегти cookie;
Location — адреса для перенаправлення;
Cache-Control — правила кешування.
Content-Type особливо важливий під час роботи з JSON:
Content-Type: application/jsonВін повідомляє серверу, що тіло запиту містить JSON.
Код стану складається з трьох цифр. Перша цифра визначає групу результату.
2xx: успіх200 OK — запит успішно виконано;
201 Created — ресурс створено;
204 No Content — запит успішний, але тіло відповіді відсутнє.
3xx: перенаправлення або кеш301 Moved Permanently — ресурс переміщено назавжди;
302 Found — тимчасове перенаправлення;
304 Not Modified — ресурс не змінився, можна використати кешовану версію.
Браузер часто обробляє перенаправлення автоматично.
4xx: помилка клієнта400 Bad Request — сервер не зміг зрозуміти запит;
401 Unauthorized — потрібна автентифікація;
403 Forbidden — доступ заборонено;
404 Not Found — ресурс не знайдено;
405 Method Not Allowed — метод не підтримується для цього ресурсу.
5xx: помилка сервера500 Internal Server Error — внутрішня помилка сервера;
502 Bad Gateway — проміжний сервер отримав некоректну відповідь;
503 Service Unavailable — сервер тимчасово недоступний.
Код 404 не означає, що інтернет не працює. Він означає, що сервер доступний, але не знайшов потрібний ресурс.
Для виконання HTTP-запитів у браузері часто використовують функцію fetch.
async function loadPost() {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}
const post = await response.json();
console.log("Заголовок:", post.title);
console.log("Текст:", post.body);
} catch (error) {
console.error("Не вдалося отримати дані:", error.message);
}
}
loadPost();Послідовність роботи цього коду:
fetch надсилає GET-запит;
сервер повертає відповідь;
response.ok перевіряє, чи код відповіді належить до успішних;
response.json() читає тіло відповіді та перетворює JSON на JavaScript-об’єкт;
catch обробляє мережеві помилки або помилки, створені вручну.
Важливо: fetch не вважає коди 404 або 500 автоматично помилкою JavaScript. Promise зазвичай залишається успішним, тому код стану потрібно перевіряти через response.ok або response.status.
Щоб надіслати JSON на сервер, потрібно:
використати відповідний HTTP-метод;
передати заголовок Content-Type;
перетворити JavaScript-об’єкт на JSON через JSON.stringify.
async function createUser() {
const user = {
name: "Олена",
email: "olena@example.com"
};
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(user)
}
);
if (!response.ok) {
throw new Error(`HTTP-помилка: ${response.status}`);
}
const createdUser = await response.json();
console.log("Створений користувач:", createdUser);
} catch (error) {
console.error("Помилка:", error.message);
}
}
createUser();JSON.stringify перетворює об’єкт:
{
name: "Олена",
email: "olena@example.com"
}на текст JSON:
{"name":"Олена","email":"olena@example.com"}Сервер отримує саме текстове тіло запиту, а заголовок Content-Type допомагає йому правильно його обробити.
Не кожен запит має тіло.
Зазвичай:
GET передає параметри в URL;
POST, PUT і PATCH часто передають дані в тілі;
DELETE може мати тіло, але це залежить від API.
Параметри для GET можуть виглядати так:
/products?category=books&limit=10У цій адресі:
category=books — один параметр;
limit=10 — інший параметр;
символ & розділяє параметри.
Не слід передавати паролі або інші секретні дані в URL: адреса може зберігатися в історії браузера, журналах сервера або заголовку переходу.
Мережевий запит може тривати невизначений час. Браузер не повинен блокувати всю сторінку, очікуючи на відповідь.
Тому fetch працює асинхронно:
console.log("До запиту");
fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((data) => {
console.log("Дані отримано:", data);
})
.catch((error) => {
console.error("Помилка:", error.message);
});
console.log("Після запуску запиту");Типовий порядок виведення:
До запиту
Після запуску запиту
Дані отримано: ...Останній рядок з’являється пізніше, коли сервер уже відповів.
Для складніших сценаріїв часто зручніше використовувати async і await, але вони також працюють асинхронно.
Браузер може зберігати копії ресурсів у кеші:
HTML;
CSS;
JavaScript;
зображень;
відповідей API.
Це зменшує кількість запитів і прискорює завантаження сторінки.
Сервер керує кешуванням через заголовки, наприклад:
Cache-Control: max-age=3600Це означає, що ресурс можна використовувати з кешу протягом певного часу.
Під час розробки кеш іноді приховує зміни. У такому разі в інструментах розробника можна вимкнути кеш або виконати повне перезавантаження сторінки.
Сервер може повідомити браузеру, що ресурс потрібно шукати за іншою адресою.
Приклад відповіді:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-pageБраузер зазвичай автоматично надсилає новий запит за адресою з Location.
Перенаправлення часто використовують:
після зміни адреси сторінки;
для переходу з HTTP на HTTPS;
після скорочених URL;
для вибору потрібної локалі або регіону.
HTTP сам по собі не зберігає стан між запитами. Кожен запит є окремим повідомленням.
Щоб сервер міг розпізнавати користувача між запитами, застосовують cookies.
Сервер може надіслати:
Set-Cookie: sessionId=abc123Браузер збереже cookie й у наступних відповідних запитах може надіслати:
Cookie: sessionId=abc123Так сервер може підтримувати:
авторизацію;
кошик покупок;
налаштування користувача;
сесію.
Не всі cookies доступні JavaScript. Cookies із прапорцем HttpOnly можуть передаватися браузером, але не читаються через document.cookie.
Інструменти розробника допомагають побачити реальний життєвий цикл запиту.
Відкрийте DevTools і перейдіть на вкладку Network. Після перезавантаження сторінки можна побачити:
адресу запиту;
HTTP-метод;
код відповіді;
час виконання;
розмір переданих даних;
заголовки;
тіло запиту;
тіло відповіді;
причину помилки.
Корисний порядок аналізу помилки:
Перевірити адресу запиту.
Перевірити HTTP-метод.
Подивитися код стану.
Переглянути заголовки.
Перевірити тіло запиту.
Перевірити тіло відповіді.
Порівняти запит із документацією API.
Браузер має правила безпеки для запитів між різними джерелами.
Джерело визначається трьома частинами:
протоколом;
доменом;
портом.
Наприклад, сторінка з одного домену може намагатися звернутися до API на іншому домені. Сервер має явно дозволити такий доступ за допомогою CORS-заголовків.
Приклад заголовка відповіді:
Access-Control-Allow-Origin: https://client.exampleЯкщо сервер не дозволив запит, браузер може заблокувати доступ JavaScript до відповіді. Це не обов’язково означає, що сервер не отримав запит. Але браузер не дасть програмі прочитати результат.
CORS — це обмеження браузера, а не загальна властивість самого HTTP.
Неправильно вважати, що успішне виконання fetch завжди означає успішну відповідь сервера.
const response = await fetch("/api/products");
if (!response.ok) {
throw new Error(`Запит завершився з кодом ${response.status}`);
}Content-TypeЯкщо тіло містить JSON, потрібно повідомити про це сервер:
headers: {
"Content-Type": "application/json"
}JSON.stringifybody для JSON-запиту має містити текст JSON:
body: JSON.stringify({ name: "Олена" })а не звичайний JavaScript-об’єкт:
body: { name: "Олена" }Мережевий запит може завершитися пізніше, ніж виконається наступний рядок коду. Дані потрібно обробляти всередині then або після await.
Запит може завершитися помилкою через:
відсутність мережі;
недоступність сервера;
помилкову адресу;
заборону CORS;
тайм-аут;
помилку в програмі сервера.
Для таких випадків використовуйте try...catch або .catch().
Не передавайте паролі, токени та приватні дані в параметрах URL. Для таких даних використовують захищене з’єднання і відповідне тіло або заголовки запиту.
HTTP описує обмін повідомленнями між клієнтом і сервером.
Життєвий цикл починається з ініціації запиту та завершується обробкою відповіді браузером.
Перед HTTP-запитом браузер знаходить IP-адресу сервера й встановлює з’єднання.
Запит містить метод, адресу, заголовки та, за потреби, тіло.
Відповідь містить код стану, заголовки та, за потреби, тіло.
Методи GET, POST, PUT, PATCH і DELETE описують тип операції.
Коди 2xx означають успіх, 4xx — помилку клієнта, 5xx — помилку сервера.
У JavaScript для HTTP-запитів у браузері часто використовують fetch.
fetch не вважає HTTP-коди 4xx і 5xx автоматично помилками, тому потрібно перевіряти response.ok.
DevTools на вкладці Network допомагають досліджувати реальні запити.
HTTPS захищає дані під час передавання, а CORS контролює доступ до відповідей між різними джерелами.