Spis treści
Masz pytanie o swoją stronę?
Umów krótką konsultację – powiem, od czego zacząć.
Kody 3xx (Redirection) to klasa kodów odpowiedzi HTTP, które mówią klientowi: „żeby dostać zasób, musisz zrobić jeszcze jeden krok”. Zwykle tym krokiem jest pobranie adresu z nagłówka Location, a w przypadku 304 sięgnięcie do kopii w pamięci podręcznej. Specyfikacja HTTP (RFC 9110) definiuje dziewięć kodów, od 300 do 308. Dla SEO liczą się cztery: 301 i 308 to przekierowania stałe – Google pokazuje w wynikach nowy adres, a 302 i 307 to przekierowania tymczasowe – w wynikach zostaje stary. Różnica wewnątrz każdej pary jest czysto techniczna: 307 i 308 gwarantują, że metoda żądania się nie zmieni (POST zostaje POST-em), a przy 301 i 302 przeglądarka może zamienić POST na GET.
Poniżej znajdziesz tabelę wszystkich kodów 300–308, różnice między parami 301/308 i 302/307, to, jak kody 3xx działają z metodą żądania i pamięcią podręczną, wyjaśnienie 303 i 304 oraz tajemniczego wpisu „307 Internal Redirect”, który widzisz w Chrome. To przegląd kodów jako części protokołu HTTP. Jeśli szukasz gotowego kodu do .htaccess, Nginx, PHP czy WordPressa, przejdź do mojego poradnika jak zrobić przekierowanie 301.
Kody HTTP 3xx (300–308) – tabela
| Kod | Nazwa | Stały / tymczasowy | Zachowuje metodę? | Kiedy używać | Wpływ na SEO |
|---|---|---|---|---|---|
| 300 | Multiple Choices | – | – | Praktycznie nigdy – serwer oferuje kilka wariantów zasobu do wyboru. | Brak praktycznego znaczenia. |
| 301 | Moved Permanently | Stały | Nie musi (POST może stać się GET) | Trwała zmiana adresu: nowy slug, struktura, domena, HTTPS, scalanie treści. | Silny sygnał, że kanoniczny jest nowy adres. W wynikach pojawia się adres docelowy. |
| 302 | Found | Tymczasowy | Nie musi (POST może stać się GET) | Zmiana na chwilę: prace serwisowe, krótka promocja, test A/B. | Słaby sygnał – w wynikach zostaje zwykle adres źródłowy. |
| 303 | See Other | Tymczasowy | Nie – kolejne żądanie to GET (lub HEAD) | Po wysłaniu formularza (wzorzec POST → przekierowanie → GET). | Google traktuje go jak przekierowanie tymczasowe. Nie do przenoszenia treści. |
| 304 | Not Modified | To nie przekierowanie | Dotyczy warunkowych GET/HEAD | Odpowiedź na żądanie warunkowe, gdy zasób się nie zmienił (cache). | Brak wpływu na indeksowanie; oszczędza transfer i zasoby przy crawlowaniu. |
| 305 | Use Proxy | – | – | Nie używać – kod wycofany (deprecated). | Brak. |
| 306 | (Unused) | – | – | Nie używać – numer zarezerwowany, kod nieużywany. | Brak. |
| 307 | Temporary Redirect | Tymczasowy | Tak – metoda musi zostać ta sama | Tymczasowe przeniesienie, gdy ważne jest zachowanie metody (API, formularze). Też jako „307 Internal Redirect” przy HSTS w przeglądarce. | Google traktuje go tak samo jak 302. |
| 308 | Permanent Redirect | Stały | Tak – metoda musi zostać ta sama | Trwałe przeniesienie z zachowaniem metody (API, endpointy przyjmujące POST). | Google traktuje go tak samo jak 301. |
Jak czytać tabelę w praktyce: przy zwykłych stronach (które przeglądarka i Googlebot pobierają metodą GET) kolumna „zachowuje metodę” nie ma znaczenia, więc wybór sprowadza się do pytania „stałe czy tymczasowe?”. Dla trwałych zmian bierzesz 301 (lub 308), dla tymczasowych 302 (lub 307).
Jak działa kod 3xx i skąd wzięły się cztery podobne kody
Pierwsza cyfra kodu odpowiedzi HTTP określa jego klasę:
- 1xx – informacyjne (żądanie przyjęte, przetwarzanie trwa),
- 2xx – sukces (np. 200 OK),
- 3xx – przekierowanie: klient musi wykonać dodatkowy krok, żeby dostać zasób,
- 4xx – błąd po stronie klienta (np. 404, 410) – więcej w artykule o błędach 404, 410 i innych kodach 4xx,
- 5xx – błąd po stronie serwera (np. 500, 503) – opisuję je w tekście o kodach 5xx.
Przekierowanie składa się zawsze z dwóch elementów: kodu 3xx i nagłówka Location z nowym adresem. Przeglądarka (albo Googlebot) odczytuje nagłówek i wysyła kolejne żądanie – już pod nowy URL. Użytkownik zwykle nie zauważa różnicy między kodami; różnica jest istotna dla wyszukiwarek, pamięci podręcznej i aplikacji wysyłających formularze.
Co dokładnie robi klient, gdy dostanie kod 3xx z nagłówkiem Location? Według RFC 9110 wysyła ponownie to samo żądanie, ale pod nowy adres. Adres w Location może być względny (np. /nowy-adres/), wtedy klient składa go z adresem pierwotnym. Przy okazji wymienia nagłówki, które zależą od adresu (np. Host), i usuwa te związane z konkretnym zasobem, np. Referer, Cookie czy Authorization, generując je na nowo dla nowego adresu. Jeśli metoda zmieniła się na GET, odpada też treść żądania (np. dane z formularza). Specyfikacja zaleca wreszcie, żeby klient wykrywał pętle przekierowań, a jej starsza wersja zalecała limit pięciu skoków. Niektóre programy nadal mają taki limit.
Skąd aż cztery „prawie takie same” kody? W HTTP/1.0 (RFC 1945, 1996) kody 301 i 302 miały zachowywać metodę żądania. Przeglądarki zaczęły jednak po przekierowaniu formularza wysyłanego metodą POST pobierać nowy adres metodą GET – i ta praktyka się utrwaliła. HTTP/1.1 (RFC 2068 i RFC 2616) dodał więc kod 303 (jawnie „zmień na GET”) i 307 (tymczasowe, bez zmiany metody), a w 2014 roku pojawił się 308 (stałe, bez zmiany metody; najpierw eksperymentalnie w RFC 7238, w 2015 roku jako standard w RFC 7538). Obecnie wszystkie kody 3xx opisuje RFC 9110 (2022), które wprost dopuszcza zmianę POST na GET przy 301 i 302 „z powodów historycznych”.
| Metoda może się zmienić (POST → GET) | Metoda musi zostać ta sama | |
|---|---|---|
| Stałe | 301 Moved Permanently | 308 Permanent Redirect |
| Tymczasowe | 302 Found | 307 Temporary Redirect |
Kod 301 vs 308 – przekierowania stałe
Oba kody znaczą to samo: zasób dostał nowy, stały adres i wszystkie przyszłe odwołania powinny używać nowego URL-a. Jedyna różnica to metoda: przy 308 klient musi powtórzyć żądanie dokładnie tą samą metodą (POST z treścią formularza trafi pod nowy adres jako POST), a przy 301 może je zamienić na GET.
Wpływ na SEO jest identyczny. Google w dokumentacji kodów HTTP pisze wprost, że 308 jest odpowiednikiem 301: robot podąża za przekierowaniem, a systemy indeksujące traktują je jako silny sygnał, że kanoniczny jest adres docelowy. Z czasem w wynikach wyszukiwania stary URL zostaje zastąpiony nowym, a sygnały (w tym linki) są konsolidowane na adresie docelowym. Popularne kiedyś twierdzenie, że 301 „gubi 10–15% mocy”, jest nieaktualne – Google od 2016 roku komunikuje, że przekierowania 3xx nie powodują utraty PageRanku.
Typowe sytuacje, w których stosujesz przekierowanie stałe:
- zmiana domeny serwisu,
- przejście z HTTP na HTTPS,
- zmiana struktury adresów URL (np. z
/post?id=123na/nazwa-artykulu/) lub zmiana slugu, - scalenie kilku podobnych artykułów w jeden, pełniejszy,
- ujednolicenie wersji domeny (z www lub bez www).
Którego użyć? Dla zwykłych stron 301 jest domyślnym i w pełni poprawnym wyborem – to on jest obsługiwany przez wszystkie narzędzia, wtyczki i panele hostingowe. 308 jest lepszy tam, gdzie pod starym adresem mogą przychodzić żądania POST, PUT czy DELETE (API, endpointy formularzy). Nie musisz też niczego poprawiać, jeśli platforma sama ustawia 308 – tak robi np. Next.js przy przekierowaniach z permanent: true (a przy tymczasowych wysyła 307). Dla Google to bez znaczenia.
Jedna rzecz, o której warto pamiętać przy obu kodach: przeglądarka może je zapamiętać i przy kolejnej wizycie w ogóle nie pytać serwera. Więcej o tym w sekcji o kodach 3xx i pamięci podręcznej.
Kod 302 vs 307 – przekierowania tymczasowe
Przekierowanie 302 (Found, w HTTP/1.0 „Moved Temporarily”) informuje, że zasób jest chwilowo pod innym adresem, a klient powinien dalej używać adresu oryginalnego. Przekierowanie 307 (Temporary Redirect) znaczy to samo, ale z twardym wymogiem: przeglądarka nie może zmienić metody żądania. W RFC 9110 przy 302 jest nawet adnotacja: jeśli zmiana POST na GET jest niepożądana, użyj 307.
Dla Google 307 to odpowiednik 302. Googlebot podąża za przekierowaniem tymczasowym, ale system indeksowania traktuje je tylko jako słaby sygnał kanonizacji – w wynikach zwykle zostaje adres źródłowy. Adres docelowy może jednak zostać zaindeksowany, jeśli wskazują na niego inne sygnały (linki, canonical, mapa witryny).
A co z 302, które „tymczasowo” działa od dwóch lat? Google ocenia przekierowania w kontekście: John Mueller wielokrotnie mówił, że długo utrzymywane 302 może zostać potraktowane jak stałe, bo Google uznaje, że właściciel strony pomylił kody. Nie ma jednak żadnego określonego terminu, po którym to następuje, więc nie opieraj na tym strategii. Jeśli zmiana jest trwała, ustaw 301 – to najprostszy sposób, żeby Google zrozumiał Twoje intencje.
Kiedy przekierowanie tymczasowe jest właściwe:
- prace serwisowe lub awaria usługi – kierujesz na stronę z informacją, a oryginalny adres ma zostać w wynikach,
- krótkotrwała promocja lub sezonowa wersja strony,
- testy A/B z osobnymi adresami wariantów – Google w wytycznych dotyczących testów zaleca w tym przypadku 302, a nie 301,
- przekierowania zależne od stanu użytkownika (np. niezalogowany → strona logowania).
Ostrożnie z automatycznym przekierowaniem na podstawie języka przeglądarki lub lokalizacji IP: Googlebot crawluje głównie z adresów w USA, więc może nigdy nie zobaczyć Twoich polskich czy niemieckich wersji. Lepiej pokazać użytkownikowi baner z wyborem wersji i oznaczyć warianty atrybutami hreflang.
Kiedy wybrać 307 zamiast 302? Gdy pod tymczasowo przeniesiony adres trafiają formularze lub wywołania API i dane z żądania POST nie mogą zginąć po drodze. Przy zwykłych stronach oba kody działają tak samo.
Jak ustawić przekierowanie 302 lub 307 w .htaccess, Nginx czy PHP, pokazuję w poradniku jak zrobić przekierowanie 301. W regułach serwera zmienia się zwykle tylko liczba (np. R=301 na R=302).
Kod 303 See Other – przekierowanie po wysłaniu formularza
Kod 303 mówi: „wynik Twojego żądania znajdziesz pod innym adresem – pobierz go metodą GET”. Nie oznacza, że zasób się przeniósł; nowy adres nie jest uważany za odpowiednik starego. Typowy przykład to wzorzec Post/Redirect/Get: użytkownik wysyła formularz (POST), serwer zapisuje dane i odpowiada 303 z adresem strony „Dziękujemy”, a przeglądarka pobiera ją metodą GET. Dzięki temu odświeżenie strony nie wysyła formularza ponownie. Tak wygląda ta wymiana w skrócie:
POST /zamowienie/ HTTP/1.1
Host: sklep.pl
HTTP/1.1 303 See Other
Location: /zamowienie/dziekujemy/
GET /zamowienie/dziekujemy/ HTTP/1.1
Host: sklep.pl
Czym 303 różni się od 302 i 307? Przy 303 kolejne żądanie to zawsze GET (lub HEAD), niezależnie od pierwotnej metody, a nowy adres nie jest odpowiednikiem starego, tylko miejscem, gdzie leży wynik operacji. Przy 307 metoda musi zostać ta sama, a przy 302 przeglądarki w praktyce i tak zmieniają POST na GET. Kod 303 może też odpowiadać na zwykłe żądanie GET. Oznacza wtedy, że serwer nie ma samego zasobu, ale wskazuje stronę, która go opisuje. Ten wzorzec spotkasz głównie w projektach Linked Data.
Z punktu widzenia SEO 303 jest przekierowaniem tymczasowym – Google wymienia go w tej samej grupie co 302 i 307. Nie używaj go do przenoszenia treści. Przekierowanie 303 to narzędzie programisty aplikacji, a nie specjalisty SEO.
Kod 304 Not Modified – cache, a nie przekierowanie
Kod 304 należy do klasy 3xx, ale nikogo nigdzie nie przekierowuje. To odpowiedź na żądanie warunkowe: przeglądarka lub robot mają już kopię zasobu i pytają serwer, czy coś się zmieniło – wysyłając nagłówek If-None-Match (z wartością ETag) lub If-Modified-Since (z datą Last-Modified). Jeśli zasób jest ten sam, serwer odpowiada 304 bez treści, a klient używa kopii z pamięci podręcznej. Oszczędza to czas i transfer.
Dla Google 304 oznacza „treść jest taka sama jak podczas poprzedniego crawlowania”. Według dokumentacji kod nie wpływa na indeksowanie (system może jedynie przeliczyć sygnały dla adresu), za to odciąża serwer przy częstym crawlowaniu dużych serwisów. Dlatego poprawnie działające ETag i Last-Modified to jeden z prostszych sposobów dbania o crawl budget. Uwaga na błędną konfigurację: serwer, który odpowiada 304 na żądania bez nagłówków warunkowych, wysyła robotowi pustą odpowiedź – a to potrafi wyrzucić stronę z indeksu.
Kody 3xx a pamięć podręczna (cache)
Kody 3xx różnią się nie tylko trwałością i metodą, ale też tym, czy przeglądarka lub serwer pośredniczący może je zapamiętać bez pytania serwera. Specyfikacja HTTP (RFC 9110) nazywa odpowiedzi 300, 301 i 308 heurystycznie cache’owalnymi. Oznacza to, że jeśli serwer nie poda nagłówków Cache-Control ani Expires, pamięć podręczna może sama oszacować, jak długo trzymać taką odpowiedź. Kody 302, 303 i 307 nie mają tej cechy i są zapamiętywane tylko wtedy, gdy serwer wprost na to pozwoli.
| Kod | Czy może trafić do cache bez nagłówków? | Co to znaczy w praktyce |
|---|---|---|
| 301, 308 | Tak (heurystycznie) | Przeglądarka może pamiętać przekierowanie nawet po usunięciu reguły z serwera. |
| 300 | Tak (heurystycznie) | Bez znaczenia w praktyce, bo kodu prawie nikt nie używa. |
| 302, 303, 307 | Nie, tylko z Cache-Control lub Expires | Klient przy kolejnej wizycie znów pyta serwer, więc zmianę lub usunięcie reguły widać od razu. |
| 304 | Nie dotyczy | To odpowiedź na pytanie o aktualność kopii, która już jest w pamięci podręcznej. |
Stąd praktyczna rada: przekierowanie 301 „ustawione na chwilę, do testów” bywa trudne do odkręcenia, bo u osób, które je już zobaczyły, może działać nadal. Jeśli nie masz pewności, czy zmiana jest ostateczna, zacznij od 302. Możesz też wysłać razem z 301 nagłówek Cache-Control z krótkim czasem ważności (np. max-age=3600). A gdy testujesz przekierowania u siebie, rób to w oknie incognito albo poleceniem curl -I, które niczego nie zapamiętuje.
Kody 300, 305 i 306 – kody, których nie spotkasz w praktyce
- 300 Multiple Choices – zasób ma kilka reprezentacji (np. różne formaty lub języki), a serwer daje klientowi listę do wyboru. Brakuje ustandaryzowanego formatu tej listy, więc kod praktycznie się nie przyjął.
- 305 Use Proxy – miał nakazywać pobranie zasobu przez wskazany serwer proxy. Został wycofany (deprecated) w RFC 7231, m.in. ze względów bezpieczeństwa – pozwalał serwerowi narzucić klientowi pośrednika.
- 306 (Unused) – numer z wcześniejszej wersji specyfikacji (szkic „Switch Proxy”), dziś nieużywany i zarezerwowany. Nigdy nie wszedł do powszechnego użycia.
„307 Internal Redirect” w Chrome – czyli HSTS
Jeśli otwierasz w Chrome adres zaczynający się od http:// i w zakładce Network narzędzi deweloperskich widzisz 307 Internal Redirect, to najprawdopodobniej nie Twój serwer wysłał ten kod. To przeglądarka sama zmieniła adres na https://, bo domena korzysta z HSTS (HTTP Strict Transport Security).
Działa to tak: serwer w odpowiedzi HTTPS wysyła nagłówek Strict-Transport-Security z czasem ważności (max-age). Przeglądarka zapamiętuje, że z tą domeną wolno łączyć się wyłącznie przez HTTPS, i przy każdej kolejnej próbie wejścia przez HTTP przepisuje adres lokalnie – zanim jakiekolwiek żądanie wyjdzie do sieci. To samo dzieje się dla domen z listy HSTS preload wbudowanej w przeglądarki (w tym całych domen najwyższego poziomu, takich jak .dev czy .app). DevTools prezentuje tę operację jako odpowiedź 307 z nagłówkiem Non-Authoritative-Reason: HSTS – „nieautorytatywna”, bo nie pochodzi od serwera.
Co z tego wynika w praktyce:
- To nie jest błąd i nie wpływa na SEO. Googlebot ani inne narzędzia nie widzą tego „przekierowania” – to mechanizm bezpieczeństwa przeglądarki.
- Nie zastępuje przekierowania na serwerze. HSTS działa dopiero po pierwszej wizycie przez HTTPS (albo dzięki liście preload) i tylko w przeglądarkach. Przekierowanie 301 z HTTP na HTTPS po stronie serwera nadal jest potrzebne dla robotów, starych linków i nowych użytkowników.
- Chcesz zobaczyć, co naprawdę zwraca serwer? Sprawdź adres
http://poleceniemcurl -I(curl domyślnie nie stosuje HSTS) albo zewnętrznym narzędziem do sprawdzania przekierowań. W samym Chrome wpis HSTS dla domeny możesz podejrzeć lub usunąć na stroniechrome://net-internals/#hsts(nie dotyczy domen z listy preload).
Łańcuchy i pętle przekierowań
Łańcuch przekierowań powstaje, gdy adres A przekierowuje na B, B na C i tak dalej. Googlebot podąża domyślnie za maksymalnie 10 przekierowaniami, ale każdy skok to dodatkowe opóźnienie. Pętla przekierowań to sytuacja, w której A prowadzi do B, a B z powrotem do A. Przeglądarka przerywa ją komunikatem „Zbyt wiele przekierowań” (ERR_TOO_MANY_REDIRECTS), a strona jest niedostępna także dla Google.
Skąd się biorą i jak je naprawić, z regułami, które przekierowują na HTTPS i wersję bez www jednym skokiem, opisuję w poradniku jak zrobić przekierowanie 301. Kody odpowiedzi tysięcy adresów naraz sprawdzisz prostym skryptem w Pythonie.
FAQ – kody 3xx
Czy kod 302 przekazuje moc SEO?
Google nie „ucina” PageRanku na żadnym przekierowaniu 3xx. Różnica polega na tym, który adres zostaje uznany za kanoniczny: przy 302 i 307 zwykle zostaje nim adres źródłowy, więc to on zbiera sygnały i pokazuje się w wynikach. Jeśli chcesz, żeby w wynikach był adres docelowy, użyj 301 lub 308.
Co jest lepsze dla SEO: 301 czy 308?
Żadne. Google traktuje 308 dokładnie tak samo jak 301. Wybór zależy od tego, czy pod starym adresem przychodzą żądania inne niż GET – jeśli tak, 308 jest bezpieczniejszy, bo zachowuje metodę i treść żądania.
Czym różni się kod 307 od 302?
Oba są tymczasowe i dla Google równoważne. 307 zabrania przeglądarce zmiany metody żądania (POST musi zostać POST-em), a 302 – „z powodów historycznych” – na taką zmianę pozwala. Jeśli kod 307 widzisz tylko w Chrome przy wejściu na adres http://, to wewnętrzne przekierowanie HSTS, a nie odpowiedź Twojego serwera.
Czy kod 3xx w Google Search Console to błąd?
Nie. Status „Strona zawiera przekierowanie” w raporcie indeksowania oznacza po prostu, że Google nie indeksuje adresu źródłowego, tylko docelowy – tak powinno być. Problemem są dopiero przekierowania w mapie witryny i linkach wewnętrznych, łańcuchy, pętle oraz 302 tam, gdzie zmiana jest trwała.
Czy kod 308 to błąd?
Nie. 308 Permanent Redirect to zwykłe przekierowanie stałe, odpowiednik 301 z zachowaniem metody żądania. Jeśli narzędzie pokazuje go jako „błąd”, zwykle chodzi o to, że strona nie odpowiada od razu kodem 200. Sprawdź, dokąd prowadzi nagłówek Location i czy nie powstaje łańcuch lub pętla. Bardzo stare programy mogą nie znać 308, bo to najmłodszy kod w tej klasie (2014).
Czy przeglądarka zapamiętuje przekierowania?
Może. Odpowiedzi 301 i 308 są według specyfikacji heurystycznie cache’owalne, więc przeglądarka może je pamiętać nawet bez nagłówków Cache-Control. 302, 303 i 307 zapamięta tylko wtedy, gdy serwer na to pozwoli. Dlatego zmiany w przekierowaniach testuj w oknie incognito albo poleceniem curl -I.
Czy 304 Not Modified może zaszkodzić stronie?
Prawidłowo użyty – nie, wręcz pomaga, bo zmniejsza obciążenie serwera. Szkodzi tylko błędna konfiguracja, gdy serwer zwraca 304 bez sprawdzenia nagłówków warunkowych albo dla zasobu, który faktycznie się zmienił – wtedy robot i użytkownicy dostają nieaktualną lub pustą treść.
Kody 3xx w pigułce
- 301 – trwała zmiana adresu zwykłej strony. Domyślny wybór przy migracjach, zmianie slugu, HTTPS i scalaniu treści.
- 308 – trwała zmiana, gdy musisz zachować metodę żądania (API, formularze). Dla Google to samo co 301.
- 302 – zmiana tymczasowa: prace serwisowe, promocja, test A/B. Stary adres zostaje w wynikach.
- 307 – zmiana tymczasowa z zachowaniem metody. Dla Google to samo co 302; w Chrome widzisz go też przy HSTS.
- 303 – przekierowanie po wysłaniu formularza, nie do przenoszenia treści.
- 304 – to nie przekierowanie, tylko odpowiedź cache; konfiguruje się je przez
ETagiLast-Modified. - 300, 305, 306 – w praktyce nieużywane (305 wycofany, 306 zarezerwowany).
Dobór kodu to połowa sukcesu – druga połowa to poprawne wdrożenie bez łańcuchów i pętli. Gotowe reguły dla Apache, Nginx, PHP, WordPressa i Cloudflare znajdziesz w poradniku jak zrobić przekierowanie 301. A jeśli serwis przeszedł kilka migracji i nie wiesz, ile starych reguł nakłada się na siebie, sprawdzę to w ramach audytu SEO: crawl całej witryny pokazuje łańcuchy, pętle i linki wewnętrzne prowadzące przez przekierowania.






Dodaj komentarz