11 min de cititInginerie

Buclă de redirecționare: cum găsești și repari ERR_TOO_MANY_REDIRECTS

O buclă de redirecționare aruncă browserul înainte și înapoi între URL-uri până renunță. Urmărește lanțul de redirecționare cu o singură comandă, identifică regula care se contrazice și repară-o definitiv.

Marius Voß
DevRel · edge infra
O buclă de redirecționare desenată ca două URL-uri care se indică reciproc, în timp ce contorul de hop-uri al browserului se epuizează și returnează ERR_TOO_MANY_REDIRECTS

O buclă de redirecționare este un lanț de redirecționări HTTP care nu ajunge niciodată la destinație: URL-ul A trimite browserul la URL-ul B, B îl trimite înapoi la A, iar după aproximativ douăzeci de hop-uri browserul renunță și afișează ERR_TOO_MANY_REDIRECTS. Nimic nu este stricat pe pagina de destinație. Două reguli pur și simplu nu sunt de acord asupra locului unde ar trebui să ajungă URL-ul, iar fiecare o anulează pe cealaltă la nesfârșit.

O redirecționare în buclă este una dintre puținele erori web care își denumește singură cauza, atâta timp cât te uiți la lucrul potrivit. Nu la browser, nu la pagina de eroare și cu siguranță nu la cache: la lanțul de redirecționare. Fiecare hop poartă un antet Location, iar cele două adrese care se tot repetă sunt cele două reguli pe care trebuie să le împaci. Acest ghid parcurge diagnosticul într-o singură comandă, cauzele din spatele aproape fiecărui ciclu de redirecționare pe care a trebuit să-l descâlcesc, și remedierea care nu creează pe tăcute o a doua buclă în altă parte. Dacă familia de redirecționări în sine e neclară, tipurile de redirecționări URL este harta; acesta este ghidul de depanare.

Ce înseamnă de fapt ERR_TOO_MANY_REDIRECTS

Browserele urmează redirecționările în numele tău, dar nu la nesfârșit. Fiecare client păstrează un buget de hop-uri și abandonează cererea când acesta se epuizează: Chrome se oprește la 20 și nu te lasă să schimbi asta, Firefox livrează aceeași valoare implicită sub network.http.redirection-limit, iar curl permite până la 50 înainte să se plângă. Standardul lasă numărul deschis. RFC 9110 spune doar că un client ar trebui să detecteze și să intervină în redirecționările ciclice, ceea ce este modul politicos al specificației de a spune că fiecare browser are nevoie de un disjunctor.

Această distincție contează pentru diagnostic, pentru că eroarea nu dovedește deloc existența unui ciclu. Un lanț de douăzeci și unu de hop-uri distincte, fără repetări, declanșează exact același mesaj ca două URL-uri care se pasează la infinit. Ambele merită reparate, dar doar una dintre situații are o pereche de adrese de împăcat. Referința de redirecționare de la MDN acoperă ambele forme, iar diferența practică apare în clipa în care afișezi lanțul.

O buclă de redirecționare între un URL HTTPS și un URL HTTP, cu contorul de hop-uri al browserului atingând limita și returnând ERR_TOO_MANY_REDIRECTS

Încă un lucru pe care pagina de eroare îl ascunde: o redirecționare permanentă este stocată în cache de browser. Dacă bucla a fost construită din răspunsuri 301, vizitatorii continuă să intre în buclă local chiar și după ce repari serverul, până când acea intrare din cache expiră sau o șterg ei înșiși. Acest singur fapt este motivul pentru care testez schimbările de redirecționare cu un 302 și le promovez la 301 doar după ce lanțul este corect, un obicei pentru care redirecționările 301 vs 302 face cazul complet.

Urmărește lanțul de redirecționare cu o singură comandă

Sari peste browser. Cel mai rapid mod de a citi orice buclă de redirecționare este terminalul, pentru că curl afișează fiecare hop în loc să le comprime într-o singură pagină de eroare:

curl -sIL https://example.com | grep -E '^HTTP|^[Ll]ocation'

Obții o linie de status și un antet Location pentru fiecare hop, în ordine. Citește-l de sus în jos și apare unul dintre trei tipare. Două URL-uri care alternează înseamnă un ciclu real, iar perechea numește ambele reguli vinovate. Un șir lung de URL-uri distincte înseamnă un lanț pe care cineva l-a tot stivuit de-a lungul anilor, fiecare hop legitim în sine. Iar un lanț care se rezolvă bine în terminal, dar tot eșuează în browser, înseamnă că bucla este cauzată de cookie-uri, pentru că curl nu trimite cookie-uri implicit.

Ultimul caz merită propria verificare, pentru că este cel care îi face pe oameni să dea vina pe DNS o după-amiază întreagă:

curl -sIL -c jar.txt -b jar.txt https://example.com/account | grep -E '^HTTP|^[Ll]ocation'

Cu un cookie jar atașat, o buclă de autentificare sau de consimțământ se reproduce în linia de comandă, unde poți vedea efectiv ce endpoint tot setează și apoi respinge sesiunea. În browser, vizualizarea echivalentă este panoul Network cu "Preserve log" activat, care împiedică ștergerea hop-urilor anterioare atunci când pagina navighează. Dacă preferi să nu deschizi deloc un terminal, verificatorul nostru de linkuri urmărește lanțul direct în browser și afișează codul de status la fiecare hop.

Cauzele din spatele aproape fiecărui ciclu de redirecționare

Odată ce poți vedea lanțul, cauza este de obicei una dintre puținele posibile. Perechea de URL-uri care se repetă îți spune la ce strat să te uiți: schema care sare înainte și înapoi indică terminarea TLS, hostname-ul care sare indică o regulă de host canonic, iar o cale care tot câștigă și pierde un slash indică ordinea regulilor de rewrite.

Reguli https în spatele unui proxy care termină TLS-ul

Aceasta este cea mai comună redirecționare infinită de pe web-ul modern, și a apărut din momentul în care proxy-urile au început să termine TLS-ul în fața originilor. Proxy-ul acceptă o cerere HTTPS de la vizitator, apoi preia originea ta prin HTTP simplu. Originea ta vede o cerere nesigură, face ce i-ai spus să facă și redirecționează către HTTPS. Proxy-ul servește acea redirecționare, este întrebat din nou, preia originea prin HTTP din nou, și tot așa. Cloudflare documentează exact acest eșec sub modul său de criptare flexibilă, iar orice alt proxy are aceeași capcană sub alt nume.

Există două remedieri clare. Schimbă proxy-ul la un mod de criptare full, ca să vorbească cu originea ta prin TLS, ceea ce este răspunsul corect în aproape toate cazurile. Sau, dacă hop-ul către origine chiar trebuie să rămână simplu, fă ca regula originii să citească antetul X-Forwarded-Proto în loc de conexiunea brută, ca să nu mai redirecționeze cererile care erau deja securizate la edge.

www și apex care nu sunt de acord asupra hostului câștigător

O regulă de host canonic e în regulă. Două dintre ele, scrise în momente diferite de oameni diferiți, sunt o buclă. Versiunea clasică are o configurație de server care trimite apex-ul la www, în timp ce configurația aplicației trimite www înapoi la apex, iar amândouă sunt convinse că au dreptate. O vei vedea instantaneu în lanț: example.com la www.example.com la example.com, la nesfârșit.

Alege un singur host, impune-l într-un singur loc, și șterge cealaltă regulă în loc să încerci să le faci să se înțeleagă. Același lucru se aplică unui rewrite de trailing-slash sau de litere mici: când două reguli normalizează același URL în direcții opuse, obții un ciclu de redirecționare chiar dacă fiecare regulă este, luată separat, rezonabilă.

Setarea de URL din CMS sau aplicație care nu mai corespunde

Majoritatea aplicațiilor își stochează propria adresă canonică, iar acel câmp este o regulă de redirecționare cu un nume prietenos. Schimbă domeniul, mută-te într-un mediu nou, sau restaurează un snapshot de bază de date de pe alt host, și aplicația începe să redirecționeze fiecare cerere către o adresă care redirecționează înapoi. Pentru că setarea trăiește în baza de date, nu în configurația serverului web, ea supraviețuiește auditului de configurație pe care tocmai l-ai făcut, ceea ce o face atât de enervant de găsit.

Semnătura este un lanț care părăsește hostname-ul tău curent și nu se mai întoarce la el. Repară adresa stocată la domeniul pe care îl servești de fapt, apoi golește orice cache de aplicație sau de pagină care a capturat adresa greșită.

Aici regulile sunt nevinovate, iar starea este problema. O poartă de acces redirecționează vizitatorii neautentificați către o pagină de login, pagina de login îi redirecționează înapoi pe cei autentificați, iar un cookie de sesiune care nu poate fi citit pe domeniul țintă lasă ambele părți convinse că cealaltă ar trebui să se ocupe de asta. Bannerele de consimțământ cauzează aceeași formă atunci când redirecționarea care setează cookie-ul de consimțământ este ea însăși blocată.

Indiciul este cel din secțiunea anterioară: o fereastră privată curată funcționează, sau curl fără un cookie jar se rezolvă normal. Verifică domeniul cookie-ului și scopul Path, atributele sale Secure și SameSite față de schema pe care o servești de fapt, și dacă este setat pe apex, dar citit pe www.

Ce se repetă în lanțCauza probabilăPrimul lucru de schimbat
http la https și înapoiProxy care termină TLS, originea insistăMod de criptare full, sau ai încredere în XFP
Apex la www și înapoiDouă reguli de host canonicȘterge una, păstrează o singură regulă
O cale care câștigă și pierde un slashReguli de rewrite în ordinea greșităNormalizează o singură dată, înainte de orice rutare
Părăsește hostname-ul tău, nu se mai întoarceAdresa stocată a site-ului e învechităRepară setarea de URL a aplicației, golește cache-ul

Buclele de redirecționare sunt rareori misterioase odată ce lanțul e pe ecran, dar chiar mănâncă o după-amiază atunci când ghicești în loc să urmărești. Dacă preferi să deții stratul de redirecționare în loc să te cerți cu el, planul gratuit Elido îți oferă linkuri a căror destinație este o singură valoare stocată, pe care o poți redirecționa oricând, cu fiecare hop înregistrat.

Repară-o fără să creezi o a doua buclă

Remedierea în sine este scurtă, iar ordinea contează mai mult decât sintaxa. Schimbă o regulă, apoi urmărește din nou lanțul. Schimbarea a trei reguli și reîncărcarea nu-ți spune nimic despre care a contat, și am văzut o echipă petrecând o oră așa pe o buclă cauzată de o regulă pe care o reparaseră deja din prima încercare.

  1. Elimină sau inversează exact una dintre cele două reguli numite de lanț, astfel încât o cerere să poată ajunge la un 200 într-un singur hop.
  2. Rulează din nou urmărirea curl -sIL și confirmă că lanțul are acum cel mult o redirecționare, fără hostname repetat.
  3. Golește cache-ul browserului, sau testează într-o fereastră privată, pentru că orice 301 servit anterior este încă stocat local în cache și va simula un eșec care nu mai există.
  4. Abia atunci promovează redirecționările temporare la unele permanente, odată ce forma lanțului este stabilită.

Două capcane stau la finalul acestei liste. HSTS este una: odată ce un host a trimis un antet Strict-Transport-Security, browserele actualizează singure fiecare cerere la HTTPS, așa că o regulă a originii care forțează și ea HTTPS devine redundantă și poate transforma o configurare greșită de proxy într-o buclă pe care n-o poți reproduce fără să ștergi intrarea HSTS. Cealaltă este cache-ul din fața buclei. Un CDN care a stocat în cache un 301 va continua fericit să-l servească după ce originea nu-l mai trimite, motiv pentru care o golire de cache aparține remedierii, nu vine după ea. Lanțurile lungi care nu intră niciodată în buclă merită scurtate în același pas: fiecare hop suplimentar este încă o șansă ca un query string să fie pierdut, ceea ce este exact modul în care parametrii UTM dispar din GA4, și e parte din motivul pentru care linkurile scurte nu trebuie să strice SEO atâta timp cât rămân la un singur hop.

Vedere înainte și după a unui lanț de redirecționare: un lanț de patru hop-uri care intră în buclă între hosturi, și aceeași cerere rezolvată printr-o singură redirecționare canonică

Linkurile scurte adaugă încă un loc unde se poate forma un ciclu, și nu este redirecționarea shortener-ului. Un link scurt este un singur hop stocat: intră slug-ul, iese destinația. Bucla apare când destinația indică înapoi, ceea ce se întâmplă mai des decât pare. Cineva editează un link de campanie ca să indice către o pagină de destinație, pagina de destinație are o regulă veche care redirecționează către URL-ul scurt pentru că aceea era adresa canonică de partajare trimestrul trecut, iar acum cele două sar între ele. Ambele hop-uri se comportă exact așa cum au fost configurate.

Mai apar alte două variante în același lanț. Una este o pereche de linkuri scurte care se indică reciproc după o editare în masă, de obicei dintr-un import de spreadsheet unde coloana de destinație conținea URL-uri scurte în loc de cele finale. Cealaltă este un domeniu personalizat care încă se rezolvă către un host ce redirecționează înapoi către shortener, ceea ce este un rest de DNS, nu o problemă de link, iar domenii personalizate pentru linkuri scurte acoperă cum ar trebui să arate înregistrările. În toate cele trei cazuri, remedierea este să setezi destinația la pagina finală, nu la o altă redirecționare, ceea ce poți face fără să atingi nimic deja tipărit sau publicat.

Pentru că destinația este stocată, nu încorporată în URL, nimic din toate astea nu necesită o retipărire. Acesta este întregul argument pentru linkurile gestionate, iar linkul scurt nu funcționează este ghidul mai larg de triaj atunci când simptomul nu este specific o buclă.

Împiedică următoarea buclă să ajungă în producție

Buclele de redirecționare sunt un bug de configurare care se strecoară în timp, așa că remedierile durabile sunt cele plictisitoare. Păstrează decizia de host canonic într-un singur loc și tratează orice a doua regulă care atinge schema sau hostname-ul ca pe un bug din prima clipă în care o vezi. Urmărește redirecționările noi cu curl -sIL înainte să le anunți, nu după ce cineva raportează o pagină goală. Dacă linkurile contează pentru venit, pune o verificare pe ele: o urmărire programată care eșuează atunci când lanțul crește peste un hop prinde drift-ul cu mult înainte s-o facă un client, iar monitorizarea redirecționărilor de linkuri arată cum arată asta conectat la alertare reală.

Obiceiul mai larg este să tratezi destinațiile ca pe niște date pe care le poți audita. Prevenirea degradării linkurilor acoperă aceeași disciplină pentru linkurile care încetează pe tăcute să se mai rezolve, și este aceeași verificare săptămânală în ambele cazuri. Sincer, majoritatea buclelor pe care le-am văzut au fost livrate de doi oameni competenți care au reparat fiecare aceeași problemă într-un strat diferit, la o lună distanță. Scrie regula o singură dată, și bucla încetează să mai fie posibilă.

Citește seria fundamentală

Acesta face parte din clusterul engineering. Pentru forma traseului de redirecționare în sine, atingerea unui p95 sub 15ms pentru redirecționări acoperă cât costă un singur hop bine-comportat, iar tipurile de redirecționări URL acoperă ce cod de status aparține unde, înainte să începi să stivuiești reguli.

Alte articole de pe blog

Întrebări frecvente

Ce înseamnă ERR_TOO_MANY_REDIRECTS?

Înseamnă că browserul a urmat o redirecționare după alta fără să ajungă vreodată la o pagină reală, a atins limita de hop-uri și s-a oprit. Pagina în sine este de obicei în regulă; două reguli de redirecționare nu sunt de acord asupra locului unde ar trebui să ajungă URL-ul, așa că fiecare o anulează pe cealaltă. Chrome afișează ERR_TOO_MANY_REDIRECTS, Firefox spune că pagina nu redirecționează corect, iar Safari raportează că au avut loc prea multe redirecționări.

Cum repar ERR_TOO_MANY_REDIRECTS?

Urmărește mai întâi lanțul, apoi elimină una dintre cele două reguli care se luptă pentru URL. Rulează curl -sIL pe adresă și citește fiecare antet Location: perechea de URL-uri care se repetă îți spune ce regulă să ștergi sau să inversezi. Vinovații obișnuiți sunt o regulă HTTPS care rulează în spatele unui proxy ce termină TLS-ul, o regulă www suprapusă peste altă regulă www, și o setare a adresei site-ului care nu mai corespunde domeniului servit.

Câte redirecționări urmează un browser înainte să renunțe?

Aproximativ douăzeci, în funcție de browser. Chrome se oprește după 20 de hop-uri, iar limita nu este configurabilă, Firefox expune același plafon sub network.http.redirection-limit cu o valoare implicită de 20, iar curl urmează până la 50, dacă nu schimbi --max-redirs. Specificația nu stabilește un număr: RFC 9110 spune doar că un client ar trebui să detecteze și să intervină în redirecționările ciclice, așa că fiecare client își alege propriul plafon.

Ștergerea cookie-urilor repară o buclă de redirecționare?

Uneori, iar asta îți spune ceva. Dacă o fereastră privată încarcă pagina fără probleme, bucla este cauzată de un cookie de sesiune sau de consimțământ învechit, nu de regulile serverului tău, iar ștergerea lui este o remediere reală pentru acel vizitator. Dacă bucla apare și într-o fereastră privată nou deschisă, cookie-urile sunt nevinovate, iar problema se află într-o regulă de redirecționare, o setare de proxy sau un câmp de URL din CMS.

De ce a început site-ul meu să intre într-o buclă după ce am activat HTTPS sau un proxy CDN?

Pentru că acum două straturi insistă amândouă asupra HTTPS, în timp ce unul dintre ele vorbește cu originea ta prin HTTP simplu. Proxy-ul cere originea pe portul 80, regula originii îl trimite înapoi la HTTPS, proxy-ul răspunde la acea cerere în același fel, iar ciclul nu se mai termină. Schimbă modul de criptare al proxy-ului la full, ca să preia originea prin TLS, sau fă ca regula ta să aibă încredere în antetul X-Forwarded-Proto în loc de conexiunea brută.

Poate un link scurt să cauzeze o buclă de redirecționare?

Da, atunci când destinația indică înapoi către linkul scurt, sau când două linkuri se indică reciproc. Editarea unui link către o pagină care la rândul ei redirecționează către URL-ul scurt este varianta obișnuită, și supraviețuiește oricărei reîmprospătări a browserului pentru că ambele hop-uri funcționează exact așa cum au fost configurate. Setează destinația la pagina finală, nu la o altă redirecționare, iar bucla dispare fără să retipărești nimic.

Încearcă Elido

Lipește un URL, obții un link scurt funcțional

Fără înregistrare. Linkul este activ timp de 30 de zile. Înregistrează-te ca să-l păstrezi pentru totdeauna.

Gratuit, fără înregistrare · 2 pe zi

Încearcă Elido

Scurtător de URL-uri găzduit în UE, cu domenii personalizate, analiză avansată și un API deschis. Nivel gratuit - fără card bancar.

Etichete
redirect loop
err_too_many_redirects
too many redirects
redirect chain
infinite redirect
301 redirect loop

Continuă lectura