HTTP od podstaw — żądania, odpowiedzi, kody statusu i nagłówki
Zrozum, jak naprawdę działa komunikacja klient-serwer. Metody HTTP, kody statusu, nagłówki, CORS, cookies i cache wyjaśnione z perspektywy frontend developera.
Jako frontend developer codziennie używasz HTTP. Każdy fetch(), każde załadowanie strony, każda integracja z API, czyli Application Programming Interface, definiuje sposób komunikacji między aplikacjami lub modułami. — to HTTP. Ale czy naprawdę rozumiesz, co się dzieje "pod spodem"?
Na rozmowach technicznych pytania o HTTP pojawiają się regularnie. "Co oznacza status 304?", "Czym różni się POST od PUT?", "Jak działa CORS?". Ten artykuł da Ci solidne fundamenty. Jeśli nie wiesz jeszcze, jak działa internet od podstaw — zacznij od tego.
Krótka odpowiedź: HTTP = request-response między klientem a serwerem. Metody: GET (pobierz), POST (utwórz), PUT (zastąp cały zasób), PATCH (aktualizuj częściowo), DELETE (usuń). Kluczowe kody: 200 OK, 201 Created, 401 (brak auth), 403 (brak uprawnień), 404 (nie znaleziono), 500 (błąd serwera). CORS blokuje przeglądarka — naprawia serwer, nie frontend.
Czym jest HTTP?
HTTP (HyperText Transfer Protocol) to protokół komunikacji między klientem (przeglądarka, aplikacja) a serwerem. Jest:
Bezstanowy — każde żądanie jest niezależne, serwer nie "pamięta" poprzednich
Semantyczny — pracujesz na metodach, URL-ach, nagłówkach i statusach; w HTTP/1.1 wiadomości są tekstowe, ale HTTP/2 i HTTP/3 używają binarnego framingu
Request-Response — klient pyta, serwer odpowiada
HTTPS
HTTPS to HTTP uruchomiony przez TLS. Dane są szyfrowane w transporcie, co chroni przed podsłuchiwaniem i modyfikacją po drodze, ale nie rozwiązuje problemów po stronie samej aplikacji.
Anatomia HTTP Request
Code
GET /api/users/123 HTTP/1.1Host: example.comAccept: application/jsonAuthorization: Bearer eyJhbGciOiJIUzI1NiIs...User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Składniki:
Linia żądania:METODA /ścieżka HTTP/wersja
Nagłówki: pary klucz-wartość
Pusta linia
Body (opcjonalne): dane wysyłane na serwer
Z body (POST/PUT):
Code
POST /api/users HTTP/1.1Host: example.comContent-Type: application/jsonContent-Length: 42{"name": "Jan", "email": "jan@example.com"}
CORS to mechanizm bezpieczeństwa przeglądarki. Domyślnie JavaScript może wysyłać żądania tylko do tego samego origin (protokół + domena + port).
Code
// Strona na https://app.example.com// ✓ Same origin — działafetch('https://app.example.com/api/users')// ✗ Cross-origin — zablokowane (domyślnie)fetch('https://api.other-domain.com/users')
Jak działa CORS?
1. Proste żądania (GET, HEAD, POST — ale tylko z Content-Type: text/plain, application/x-www-form-urlencoded lub multipart/form-data i bez niestandardowych nagłówków):
Każde żądanie z nagłówkiem Authorization, Content-Type: application/json lub innym niestandardowym nagłówkiem — nawet zwykły GET — nie jest "prostym żądaniem" i wymusza preflight. Przeglądarka najpierw wysyła OPTIONS:
HttpOnly — niedostępne dla JavaScript (ochrona przed XSS)
Secure — tylko przez HTTPS
SameSite — ochrona przed CSRF (Strict/Lax/None); od Chrome 80 (2020) przeglądarki domyślnie traktują cookie bez SameSite jako Lax — nie płynie w cross-site requestach, jeśli nie ustawisz atrybutu jawnie
Max-Age/Expires — czas życia
Domain/Path — zakres obowiązywania
Wysyłanie cookies z fetch:
Code
// Domyślnie fetch NIE wysyła cookies cross-originfetch('https://api.example.com/user', { credentials: 'include' // wyślij cookies})// Same-origin: credentials: 'same-origin' (domyślne)
Żeby to zadziałało cross-origin, serwer musi też odpowiedzieć Access-Control-Allow-Credentials: true, wskazać konkretny origin zamiast *, a same ciasteczka często wymagają SameSite=None; Secure.
Cache HTTP
Cache-Control
Code
Cache-Control: max-age=3600 // cachuj przez 1hCache-Control: no-cache // zawsze waliduj z serweremCache-Control: no-store // nigdy nie cachujCache-Control: private // tylko cache przeglądarkiCache-Control: public // można cachować wszędzie
ETag i walidacja
Code
// Pierwsza odpowiedźHTTP/1.1 200 OKETag: "abc123"Content-Type: application/json{"data": "..."}
Code
// Kolejne żądanie z ETagGET /api/data HTTP/1.1If-None-Match: "abc123"// Jeśli dane się nie zmieniły:HTTP/1.1 304 Not Modified// Brak body — użyj cache
Praktyczne przykłady z fetch
GET z obsługą błędów
Code
async function getUser(id) { const response = await fetch(`/api/users/${id}`) if (!response.ok) { if (response.status === 404) { throw new Error('Użytkownik nie istnieje') } throw new Error(`HTTP Error: ${response.status}`) } return response.json()}
async function uploadFile(file) { const formData = new FormData() formData.append('file', file) const response = await fetch('/api/upload', { method: 'POST', body: formData, // Content-Type ustawia się automatycznie }) return response.json()}
FAQ
Czym jest HTTP i jak działa?
HTTP (HyperText Transfer Protocol) to protokół komunikacji klient-serwer. Klient (przeglądarka, aplikacja) wysyła request z metodą, URL, nagłówkami i opcjonalnym body. Serwer odpowiada kodem statusu, nagłówkami i body z danymi. HTTP jest bezstanowy — każdy request jest niezależny, serwer nie "pamięta" poprzednich. HTTPS to HTTP z szyfrowaniem TLS, które chroni transmisję przed podsłuchiwaniem.
Jaka różnica między PUT a PATCH w HTTP?
PUT zastępuje cały zasób — wysyłasz kompletną reprezentację obiektu (wszystkie pola). Jeśli pole nie jest w body, zostaje usunięte lub zresetowane. PATCH aktualizuje częściowo — wysyłasz tylko zmienione pola. PUT jest idempotentny (wielokrotne wywołanie = ten sam wynik). PATCH formalnie nie musi być idempotentny, choć wiele API tak go implementuje. W praktyce: edytujesz email użytkownika? PATCH. Zastępujesz cały profil? PUT.
Co oznacza 401 vs 403 w HTTP?
401 Unauthorized oznacza, że użytkownik nie jest uwierzytelniony — nie podał credentiali lub token jest nieważny. Nazwa jest myląca (historycznie). 403 Forbidden oznacza, że użytkownik jest uwierzytelniony ale nie ma uprawnień do zasobu. Praktyka: 401 → przekieruj do logowania. 403 → pokaż komunikat "brak dostępu", nie logowania. 404 zamiast 403 bywa używane gdy chcesz ukryć samo istnienie zasobu.
Co to jest CORS i jak go naprawić?
CORS (Cross-Origin Resource Sharing) to mechanizm bezpieczeństwa przeglądarki blokujący requesty do innego origin (inna domena, port lub protokół). Frontend nie może ominąć CORS — blokadę wymusza przeglądarka. Naprawia się po stronie serwera: dodaj nagłówek Access-Control-Allow-Origin: https://twoja-domena.com. Dla złożonych requestów (PUT, nagłówki niestandardowe) serwer musi obsługiwać preflight OPTIONS. W dev: używaj proxy Next.js lub cors middleware w Express.
Co to jest idempotentność w HTTP?
Operacja jest idempotentna gdy wielokrotne wywołanie z tymi samymi parametrami daje ten sam wynik co pojedyncze wywołanie. GET (pobierz user) → za każdym razem ten sam user. PUT (zastąp user) → za każdym razem ten sam stan. DELETE (usuń user) → user jest usunięty, nie ma znaczenia czy wywołałeś 1 raz czy 5. Nie idempotentne: POST → każde wywołanie może tworzyć nowy zasób. To ma znaczenie przy retry logic — bezpiecznie powtarzasz tylko idempotentne operacje.
Jak działa cache HTTP?
Serwer ustawia Cache-Control: max-age=3600 — przeglądarka cachuje na 1 godzinę i nie pyta ponownie. Po wygaśnięciu: serwer zwraca ETag: "abc123", przeglądarka wysyła If-None-Match: "abc123" — jeśli dane się nie zmieniły, serwer odpowiada 304 Not Modified bez body (szybciej, mniej danych). Cache-Control: no-cache zawsze waliduje z serwerem. no-store nigdy nie cachuje. private tylko cache przeglądarki (nie CDN, czyli Content Delivery Network, przyspiesza dostarczanie zasobów z serwerów bliższych użytkownikowi.).
Jaka różnica między HTTP/1.1 a HTTP/2?
HTTP/1.1: każdy request wymaga osobnego połączenia TCP (lub kolejkuje w jednym — head-of-line blocking). Wiadomości tekstowe. Przeglądarka otwiera zwykle kilka równoległych połączeń per origin. HTTP/2: multiplexing — wiele requestów przez jedno połączenie TCP jednocześnie. Binarny format (szybszy parsing). Header compression (HPACK). Efekt: przy wielu małych requestach HTTP/2 jest znacznie szybsze. Historycznie istniał też mechanizm Server Push, ale nie stał się trwałą przewagą HTTP/2 i dziś nie warto traktować go jako głównego argumentu architektonicznego.
Zrozumienie HTTP to fundament pracy z API i projektowania REST API. Na rozmowie pokaż, że wiesz nie tylko jak użyć fetch(), ale też co dzieje się pod spodem.
Jeśli chcesz uporządkować backendowe fundamenty aplikacji i uniknąć typowych błędów architektonicznych już na starcie, skontaktuj się ze mną. Pomagam przekładać wiedzę techniczną na rozwiązania, które da się sensownie utrzymać i rozwijać.
Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.
Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.
Astro.js vs Next.js — które narzędzie wybrać w 2026 roku?
Fachowe porównanie Astro.js i Next.js z perspektywy developera pracującego na co dzień w Next.js. Architektura, wydajność, SEO, DX, koszty i konkretne use case — z benchmarkami i przykładami kodu.
WordPress → Next.js — migracja treści, redirecty 301 i zachowanie pozycji SEO
Jak przenieść stronę z WordPress na Next.js bez utraty pozycji w Google? Eksport treści, mapowanie URL, redirecty 301, migracja obrazów i weryfikacja indeksacji.
Google Search Console + Next.js — indeksacja, błędy, performance i co z nimi robić
Jak korzystać z Google Search Console dla strony Next.js? Weryfikacja, sitemap, indeksacja, Core Web Vitals, crawl budget i najczęstsze problemy — praktyczny poradnik.