Dobór przekierowania witryny: znaczenie kodów 301, 302, 307 i 308

Management Summary
Przekierowanie informuje przeglądarkę lub program, że żądany zasób znajduje się pod innym adresem. Jest częste przy przenoszeniu witryn, lecz wybór ma szczególne znaczenie dla formularzy. Niektóre przekierowania mogą zamienić wysłanie danych w zwykłe pobranie strony i utracić pierwotną treść. Artykuł wyjaśnia, dlaczego kody 307 i 308 zachowują rodzaj żądania przy przeniesieniu tymczasowym i trwałym, a 301 i 302 mogą zachować się inaczej. Właściwy wybór pomaga zachować kompletne zgłoszenia.
Spis treści
Przekierowanie prosi klienta o użycie innego adresu URL. Istotne są dwie decyzje: czy przeniesienie jest trwałe oraz czy następne żądanie ma powtórzyć metodę i treść. GET zwykle pobiera stronę, a POST często przesyła dane, na przykład wypełniony formularz. Rozróżnienie jest szczególnie ważne dla formularzy i API.
Otrzymanie przekierowania nie dowodzi wykonania kolejnego żądania ani przyjęcia danych przez cel. Zachowanie przeglądarki, ustawienia biblioteki i cały łańcuch wymagają osobnych kontroli.

Dwa pytania i cztery popularne kody
| Kod | Znaczenie | Obsługa POST |
|---|---|---|
| 301 | Trwałe przeniesienie | HTTP dopuszcza zmianę na GET; przeglądarki zwykle tak postępują. |
| 302 | Tymczasowy cel | HTTP dopuszcza zmianę na GET; przeglądarki zwykle tak postępują. |
| 307 | Tymczasowy cel | Automatyczne podążenie musi zachować metodę. |
| 308 | Trwałe przeniesienie | Automatyczne podążenie musi zachować metodę. |
Zmiana POST na GET oznacza, że pierwotna treść żądania nie jest wysyłana ponownie. Przy 307 i 308 podążenie zwykle ponawia treść; klient może jednak odmówić albo przerwać operację, jeśli treści nie da się odtworzyć. Zachowanie metody nie gwarantuje identycznych cookies, nagłówków uwierzytelniania ani wyniku aplikacji.
303 See Other ma inny cel: po przetworzeniu POST serwer może wskazać stronę wyniku pobieraną przez GET. Pasuje to do schematu Post/Redirect/Get. Kod 303 nie służy do ponownego wysłania tych samych danych formularza pod inny endpoint.
Co dzieje się przy każdym skoku
Location może zawierać względne odwołanie URI, rozwiązywane względem adresu żądania. Gdy podążanie jest włączone, klient wykonuje kolejne żądanie. Odpowiedź przekierowująca może mieć własną treść, możliwą do obejrzenia bez automatycznego podążania. Nie każda odpowiedź 3xx jest przekierowaniem nawigacji: przykładowo 304 dotyczy ponownego użycia zapisanej odpowiedzi.
Dodatkowe żądanie sieciowe wymaga pracy, ale niekoniecznie nowego zapytania DNS lub połączenia. Pamięć DNS, ponowne użycie połączeń i pamięć HTTP wpływają na koszt. HSTS może również lokalnie zmienić HTTP na HTTPS bez odpowiedzi 301 serwera. Stała liczba milisekund na skok nie jest więc regułą ogólną.
Przechowywanie a trwałość przeniesienia
Kody 301 i 308 kwalifikują się do heurystycznego buforowania według reguł HTTP. Tymczasowe odpowiedzi, takie jak 302, również mogą być buforowane przy odpowiednich jawnych informacjach o świeżości. Tymczasowe nie oznacza „nigdy niezapisywane”. Nadal znaczenie mają metoda, dyrektywy pamięci i inne ograniczenia.
Cache-Control: max-age=3600 określa czas świeżości, a nie gwarantowane usunięcie po godzinie. Nieświeża odpowiedź może pozostać zapisana i podlegać walidacji; inne reguły wpływają na ponowne użycie. Zmiana reguły serwera nie odwołuje natychmiast przekierowania zapisanego u wszystkich klientów.
Błędne trwałe przekierowanie wymaga skoordynowanej korekty. Odesłanie celu do starego adresu może utworzyć pętlę u klientów zachowujących pierwsze przekierowanie. Kontrola obejmuje świeżą i istniejącą pamięć, a odnośniki oraz klienci otrzymują docelowy adres.
Sygnał dla wyszukiwarki nie gwarantuje pozycji
Google traktuje trwałe przekierowania jako silny sygnał wyboru celu jako adresu kanonicznego, czyli głównego adresu wybranego do indeksowania, a tymczasowe jako słabszy. Nie oznacza to zachowania starego URL na zawsze przy 302 ani natychmiastowego przeniesienia określonej pozycji przy 301. Ponowne indeksowanie i inne sygnały pozostają istotne.
Dokumentacja migracji Google stwierdza, że trwałe przekierowania same w sobie nie powodują utraty PageRank. Skracanie łańcuchów nadal pomaga w opóźnieniu, niezawodności i limitach crawlera. Twierdzenie o nieuniknionej utracie sygnału przy każdym skoku jest mylące. Bezpośrednie przekierowanie do właściwego celu jest korzystne, jeśli wymagane zachowanie na to pozwala.
Cookies, źródło przejścia i uwierzytelnianie
Origin składa się z protokołu, nazwy hosta i portu, bez ścieżki strony. Zmiana hosta nie usuwa automatycznie nagłówka Referer. Przy popularnej regule strict-origin-when-cross-origin bezpieczne żądanie do innego origin zwykle zachowuje origin, lecz pomija ścieżkę. Przy przejściu do HTTP informacja jest pomijana. Wynik zależy od rzeczywistej polityki i kontekstu żądania.
Cookie przypisane wyłącznie do hosta nie obejmuje poddomen. Poprawny atrybut Domain może je obejmować, z uwzględnieniem Path, Secure, SameSite i zasad przeglądarki. Dane dostępowe i nagłówki Authorization podlegają dodatkowym ograniczeniom. Sam tytuł strony końcowej nie potwierdza zachowania logowania lub uprawnień API.
Mały odtwarzalny test metod
Izolowany test na interfejsie lokalnym z curl 8.14.1 wysłał nieszkodliwą treść test=1 do pięciu sztucznych przekierowań. Przy zwykłym --location --data test=1 kody 301, 302 i 303 dotarły jako GET bez treści, natomiast 307 i 308 jako POST z zachowaną treścią. Jawna opcja curl --post301 zachowała POST także po 301. Pokazuje to znaczenie ustawień klienta.
Test obejmuje tylko tę konfigurację curl. Nie mierzy pamięci przeglądarki, prawdziwych formularzy, zewnętrznych witryn ani przekazywania danych dostępowych. Historyczne wyniki dla dwunastu stron nie są tutaj przedstawiane jako potwierdzony pomiar.
Kontrola całego łańcucha
Przydatny zapis obejmuje początkowy URL i metodę, każdy status i Location, końcowy adres, metodę, obsługę treści żądania oraz końcowy status odpowiedzi. Kod 403 na końcu to odmowa dostępu, a nie dowód konkretnej przyczyny przekierowania. Pętla lub limit skoków klienta może przerwać łańcuch przed osiągnięciem strony końcowej.
Inspektor indeksowania korzystający z GET pomaga sprawdzić adresy, ale nie dowodzi zachowania POST. Migracja formularza lub API wymaga rzeczywiście obsługiwanego klienta i nieszkodliwych danych testowych. Przy trwałym przeniesieniu endpointu 308 jest właściwym sygnałem zachowującym metodę. Aktualizacja adresów klientów usuwa długotrwałą zależność od obsługi przekierowań.

Pytania i odpowiedzi
Dlaczego 303 po wysłaniu formularza zapobiega ponownemu przesłaniu danych przy odświeżeniu strony?
Po odpowiedzi 303 przeglądarka pobiera stronę wyniku metodą GET i właśnie to żądanie GET powtarza odświeżenie. Dane formularza nie trafiają więc do serwera po raz drugi. Nie chroni to jednak przed podwójnym kliknięciem przycisku wysyłania; do tego aplikacja potrzebuje własnej kontroli.
Endpoint API zostaje trwale przeniesiony. Czy wystarczy przekierowanie 308?
Jako rozwiązanie przejściowe tak, jako stałe – rzadko. 308 informuje, że przeniesienie jest trwałe, a metoda musi zostać zachowana, jeśli klient automatycznie podąża za przekierowaniem. To, czy podąża, zależy od klienta: niektóre biblioteki w ogóle nie obsługują przekierowań albo robią to dopiero po zmianie ustawień, a treść żądania, której nie da się odczytać ponownie, na przykład strumień, może zawieść przy drugim wysłaniu.
Do tego dochodzą uwierzytelnianie i pamięć podręczna. Dane dostępowe i nagłówki Authorization podlegają przy przekierowaniach własnym ograniczeniom; przy zmianie hosta wielu klientów ich nie przekazuje, a nowy endpoint odrzuca wtedy żądanie, choć metoda jest prawidłowa. Ponadto 308 kwalifikuje się do heurystycznego przechowywania. Błędnie ustawione trwałe przekierowanie może więc działać u części klientów jeszcze po zmianie reguły na serwerze.
Wiarygodny jest dlatego test z klientami, którzy faktycznie korzystają z API, z nieszkodliwymi danymi testowymi i z zapisem aż do końcowej metody i statusu odpowiedzi. Następnie klienci powinni używać nowego adresu bezpośrednio, a przekierowanie obsługuje już tylko spóźnionych klientów.


