Dokumentacja

Skróć łańcuchy przekierowań

Skróć łańcuchy przekierowań

Przekierowanie wysyła przeglądarkę pod inny adres, zanim cokolwiek się załaduje. Jedno jest normalne: http:// na https:// albo www na adres bez niego. Każdy dodatkowy skok to kolejna droga do serwera i z powrotem, często z nowym połączeniem i negocjacją TLS. Na telefonie to kilkaset milisekund pustego ekranu na każdy skok, zanim strona w ogóle zacznie się ładować. Wyszukiwarki też podążają za łańcuchami, ale tracą na nie czas indeksowania i po kilku skokach się poddają.

Lista kontrolna strony podąża od adresu używanego przez Twój monitor do strony końcowej i oczekuje najwyżej jednego przekierowania.

Jak powstają łańcuchy

Typowy łańcuch rośnie z reguł, z których każdą dodał z dobrego powodu ktoś inny, w innym miejscu:

Krok Adres Kto przekierowuje
1 http://www.example.com/ → https://www.example.com/ przełącznik "force HTTPS" w panelu hostingu
2 https://www.example.com/ → https://example.com/ reguła www w .htaccess lub w CDN
3 https://example.com/ → https://example.com/en/ wtyczka językowa

Trzy skoki tam, gdzie wystarczy jeden. Poprawka jest zawsze ta sama: każdy wariant trafia prosto na adres końcowy jedną regułą. http://www.example.com/cokolwiek powinien wylądować na https://example.com/cokolwiek jednym 301.

Inne częste przyczyny:

  • Ukośnik na końcu. /about → /about/ (lub odwrotnie) dodaje skok, gdy linki i menu używają drugiej formy.
  • Niezgodny adres w CMS. WordPress przekierowuje na adres ze swoich ustawień. Jeśli jest tam https://www.example.com, a serwer wysyła odwiedzających na adres bez www, reguły walczą ze sobą: drugi skok albo pętla.
  • CDN plus serwer źródłowy. Cloudflare przekierowuje http na https, potem serwer przekierowuje www na domenę bez www. Każda reguła osobno jest w porządku, razem dają dwa skoki.
  • Stare przekierowania wskazujące na stare przekierowania. /stary → /nowszy → /najnowszy, po dwóch redesignach.

Sprawdź sam

Podążaj za łańcuchem i wypisz każdy krok. Zamiast example.com wpisz swoją stronę:

curl -sIL http://www.example.com/ | grep -iE '^(HTTP/|location:)'

Każda linia location: to jedno przekierowanie. Naprawione oznacza jedną linię location: albo żadnej, gdy zaczynasz od adresu końcowego.

Wszystkie cztery warianty naraz:

for u in http://example.com/ http://www.example.com/ https://example.com/ https://www.example.com/; do
  curl -sL -o /dev/null -w "$u → %{url_effective} (%{num_redirects} redirects)\n" "$u"
done

Każda linia powinna kończyć się na tym samym adresie z 1 lub 0 przekierowań.

Uwaga: Przeglądarki, które znają już nagłówek HSTS Twojej strony, wykonują skok z http:// wewnętrznie. Nowi odwiedzający, roboty wyszukiwarek i curl nie, więc go licz.

Jak to naprawić

Ustal, skąd pochodzi każdy skok (wynik curl pokazuje kolejność), zostaw jedno miejsce, które zna adres końcowy, a pozostałe wyłącz lub przepisz. Wybierz to, do czego masz dostęp.

WordPress

  1. Settings → General: WordPress Address (URL) i Site Address (URL) muszą być dokładnie adresem końcowym, z https:// i z www lub bez, tak jak przekierowuje serwer. Niezgodność powoduje dodatkowy skok na każdej podstronie.
  2. Wtyczki przekierowań. We wtyczce Redirection (Tools → Redirection) albo w przekierowaniach Yoast SEO Premium lub Rank Math szukaj łańcuchów: jeśli /stary wskazuje na /nowy, a /nowy na /najnowszy, ustaw /stary bezpośrednio na /najnowszy.
  3. Wtyczki HTTPS. Jeśli na https przekierowuje Really Simple SSL i jednocześnie hosting, zostaw jedno. Przekierowanie wtyczki działa dopiero po uruchomieniu PHP, więc reguła serwera jest szybsza.
  4. Wtyczki językowe. Jeśli / przekierowuje na /en/, WPML i Polylang potrafią serwować domyślny język bez katalogu językowego albo przestać przekierowywać według języka przeglądarki. To usuwa skok dla strony głównej.
  5. Bezpośrednie odnośniki. W menu i treści używaj linków w tej samej formie co w Settings → Permalinks (z ukośnikiem na końcu lub bez), żeby WordPress ich nie przekierowywał.

Potem wyczyść cache stron (WP Rocket, LiteSpeed Cache, cache hostingu).

cPanel

cPanel ma dwa osobne przełączniki, które łatwo nałożyć na siebie: Domains → Domains → Force HTTPS Redirect i regułę www w Domains → Redirects. Razem sprawiają, że http://www wymaga dwóch skoków.

Wyłącz oba i zamiast nich użyj jednej reguły w .htaccess:

  1. Otwórz Files → File Manager, przejdź do public_html i w Settings zaznacz Show Hidden Files (dotfiles).
  2. Edytuj .htaccess i umieść blok z zakładki Apache i LiteSpeed na samej górze, przed sekcją # BEGIN WordPress, jeśli istnieje.
  3. Przetestuj pętlą curl powyżej.

Plesk

  1. Websites & Domains → example.com → Hosting & DNS → Hosting: w Preferred domain ustaw wybraną formę (z www lub bez) i włącz Permanent SEO-safe 301 redirect from HTTP to HTTPS.
  2. Usuń dodatkowe reguły www lub https, które dodałeś w tym samym celu do .htaccess albo do Apache & nginx Settings.
  3. Przetestuj wszystkie cztery warianty pętlą curl powyżej. Jeśli http://www nadal wymaga dwóch skoków, wyłącz przełączniki Pleska i użyj jednej reguły (zakładka nginx lub Apache).

nginx

Typowy błąd to blok dla portu 80, który zachowuje hosta (https://$host$request_uri), więc http://www trafia najpierw na https://www. Wpisz host końcowy wprost. Na Debianie i Ubuntu strona jest w /etc/nginx/sites-available/example.com, na Rocky, Alma i CentOS w /etc/nginx/conf.d/example.com.conf:

# Każde żądanie http, z www lub bez: jeden skok na adres końcowy.
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

# https://www: również jeden skok.
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name www.example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    return 301 https://example.com$request_uri;
}

Certbot dodaje bloki if ($host = www.example.com) { return 301 https://$host$request_uri; }; zachowują one www i tworzą dodatkowy skok. Zastąp je blokami powyżej.

Przetestuj i zastosuj:

sudo nginx -t && sudo systemctl reload nginx

Apache i LiteSpeed

Jedna reguła dla http i www naraz, na górze .htaccess albo w wirtualnym hoście:

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

Usuń starsze reguły, które robią tylko jedno z dwóch, inaczej nadal wykonają się pierwsze. Jeśli wolisz www, użyj RewriteCond %{HTTP_HOST} !^www\. [NC] i https://www.example.com.

Ostrzeżenie: Za Cloudflare lub innym proxy %{HTTPS} ma wartość off także dla odwiedzających na https, i ta reguła tworzy pętlę. Zamiast pierwszego warunku użyj RewriteCond %{HTTP:X-Forwarded-Proto} !https albo zrób przekierowanie w Cloudflare (zakładka Cloudflare).

Na własnym serwerze przetestuj i przeładuj (na Rocky, Alma i CentOS zamiast apache2 użyj httpd):

sudo apachectl configtest && sudo systemctl reload apache2

Cloudflare

Always Use HTTPS (SSL/TLS → Edge Certificates) wysyła http://www na https://www; osobne przekierowanie www dodaje potem drugi skok. Utwórz jedną regułę przekierowania, która łapie oba przypadki:

  1. Przejdź do Rules → Redirect Rules i Create rule.

  2. Custom filter expression, potem Edit expression:

    (http.host eq "www.example.com") or (not ssl)
    
  3. URL redirect: typ Dynamic, wyrażenie concat("https://example.com", http.request.uri.path), status 301, zaznacz Preserve query string i Deploy.

Żeby reguła działała, host www potrzebuje rekordu DNS przez proxy (pomarańczowa chmurka). Potem sprawdź, czy serwer źródłowy nie przekierowuje ponownie: jeśli WordPress lub serwer nadal wysyła odwiedzających na www, powstaje pętla. Krawędź i serwer źródłowy muszą zgadzać się co do jednego adresu końcowego.

Node.js i Next.js

Next.js domyślnie przekierowuje /about/ na /about (308), a z trailingSlash: true odwrotnie. W linkach używaj tej samej formy. Dla www wystarczy jedna reguła w next.config.js:

module.exports = {
    async redirects() {
        return [
            {
                source: '/:path*',
                has: [{ type: 'host', value: 'www.example.com' }],
                destination: 'https://example.com/:path*',
                permanent: true,
            },
        ];
    },
};

Na Vercel lub Netlify ustaw przekierowanie między www a domeną bez www raczej w ustawieniach domen projektu i zostaw tylko jedno z dwóch. Jeśli przed aplikacją stoi nginx, umieść przekierowanie tam (zakładka nginx), a nie w obu miejscach.

Platformy hostowane

Shopify, Wix, Squarespace i Webflow przekierowują każdą inną domenę na tę oznaczoną jako główna, jednym skokiem. Sprawdź, czy domena główna to ta, do której linkujesz: w Shopify Settings → Domains, w Webflow domyślna domena w Site settings → Publishing. Łańcuch na tych platformach zwykle pochodzi z Twoich wpisów na liście przekierowań URL platformy, które wskazują na adresy przekierowujące dalej.

Potwierdź poprawkę

Uruchom ponownie pętlę curl z sekcji Sprawdź sam, potem otwórz cel w PulseKeeper i kliknij Sprawdź teraz na zakładce Lista kontrolna. Pozycja zmieni się na OK w ciągu kilku minut, a nie dopiero przy kolejnym codziennym sprawdzeniu.