Перейти к содержимому

ERR_TOO_MANY_REDIRECTS - слишком много перенаправлений

Браузер показывает «слишком много перенаправлений» и страницу не открывает. Разбираем причины цикла по убыванию частоты.

С чего начать

Смотрим саму цепочку переходов:

Окно терминала
curl -sIL -o /dev/null -w '%{url_effective} %{num_redirects}\n' https://example.com/
curl -sI https://example.com/ | grep -iE '^(HTTP/|location)'
# цикл виден сразу: адрес перехода совпадает с запрошенным или чередуется с ним

Цепочка отвечает на главный вопрос: между какими двумя адресами мечется браузер. Пара «с www и без» указывает на спор правил, пара «защищённый и обычный» - на потерянный признак протокола.

Ищем, кто ставит переход:

Окно терминала
grep -rn 'return 30\|rewrite .*permanent' /etc/nginx/ 2>/dev/null | head
grep -rn 'Redirect\|RewriteRule' /home/bitrix/www/.htaccess | head
grep -rn 'LocalRedirect' /home/bitrix/www/local /home/bitrix/www/bitrix/php_interface | head
# правило находится в одном из трёх мест: веб-сервер, файл настроек, свой код

Одно правило цикла не даёт. Цикл появляется, когда правил два и каждое считает правильным свой адрес, либо когда одно правило ловит и тот адрес, на который само же отправляет.

Проверяем, что видит сайт за посредником:

printf("протокол=%s заголовок=%s хост=%s\n",
$_SERVER['HTTPS'] ?? 'off',
$_SERVER['HTTP_X_FORWARDED_PROTO'] ?? 'нет',
$_SERVER['HTTP_HOST'] ?? '');
// признак защищённого протокола выключен при живом заголовке - типичный цикл

Сайт за балансировщиком получает обычный запрос и считает соединение незащищённым. Правило отправляет посетителя на защищённый адрес, посредник снова приходит по обычному, и круг замыкается.

Проверяем правило под нужным протоколом:

Окно терминала
curl -sI -H 'X-Forwarded-Proto: https' http://127.0.0.1/ | grep -iE '^(HTTP/|location)'
curl -sI -H 'Host: example.com' http://127.0.0.1/ | head -3
# запрос прямо к серверу минует посредника и показывает, чей это переход

Запрос напрямую к серверу отделяет его собственные правила от правил посредника. Если цикл виден и здесь, разбираться с балансировщиком бессмысленно: правило живёт на самом сервере.

Ставим правило с исключением адреса назначения:

server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri; # только с обычного порта
}
# правило на защищённом порту отправляло бы посетителя на самого себя

Переход ставят на том сервере, откуда уходят, а не на том, куда приходят. Общее правило для обоих портов сразу и даёт классический цикл из двух одинаковых адресов.

Причины

  1. Правила стоят сразу в двух местах и спорят примерно 30% случаев

    ПризнакБраузер мечется между двумя адресами: с www и без или со слешем и без него.

    ПроверкаИщем правила перехода в настройках веб-сервера и в файле настроек сайта в корне.

    Что делатьОставляем правило в одном месте, остальные убираем: канонический адрес должен быть один.

  2. Сайт за прокси не знает о защищённом протоколе примерно 25% случаев

    ПризнакЦикл появился после подключения защиты от атак, балансировщика или облачного сервиса.

    ПроверкаСмотрим признак защищённого протокола и заголовки, которые приходят от посредника.

    Что делатьНастраиваем передачу протокола на стороне посредника и его чтение на сайте.

  3. Правило ловит адрес, на который само отправляет примерно 20% случаев

    ПризнакЦикл виден только на части сайта: на одном разделе, на служебных адресах или на адресах без слеша.

    ПроверкаЧитаем условие правила и проверяем, подпадает ли под него сам адрес назначения.

    Что делатьДобавляем в условие исключение для адреса назначения и для служебных путей платформы.

  4. Переход ставит свой код на раннем событии примерно 15% случаев

    ПризнакВ настройках веб-сервера правил нет, а переход всё равно происходит на каждой странице.

    ПроверкаИщем вызовы перехода в файле обработчиков и в подключаемых файлах своего решения.

    Что делатьПравим условие перехода: оно не должно выполняться на той странице, куда сам переход и ведёт.

  5. Браузер помнит постоянный переход примерно 10% случаев

    ПризнакПравило уже исправлено, у коллег сайт открывается, а на одной машине цикл остался.

    ПроверкаОткрываем сайт в окне без истории или на другом устройстве и сравниваем поведение.

    Что делатьЧистим кэш браузера и промежуточных серверов: постоянный переход запоминается надолго.

Частые вопросы

Почему цикл появился после установки сертификата?

Правило перехода на защищённый адрес добавлено, а сайт признака защищённого соединения не видит. Так бывает за балансировщиком и за облачным сервисом защиты, где шифрование заканчивается раньше сайта.

Где правильнее ставить правило перехода?

На веб-сервере: он отвечает раньше, дешевле и без запуска платформы. Правила в файле настроек и в коде оставляют для случаев, где нужна логика самого сайта.

Постоянный или временный переход выбрать при отладке?

На время отладки временный: он не запоминается ни браузерами, ни поисковыми системами. Постоянный ставят, когда правило проверено и адрес окончательный.

Почему цикл виден только у части посетителей?

Разные пути к сайту: кэш браузера, промежуточный сервер провайдера или отдельный узел балансировщика с другой настройкой. Проверяют запросом с двух разных сетей.

Может ли цикл идти из административной части?

Да, если в настройках сайта задан один адрес, а фактически сайт открывают по другому. Платформа отправляет посетителя на канонический адрес, а веб-сервер возвращает обратно.

Смежное

Первоисточник