Чтобы прояснить ситуацию,это НЕ повторяющийся вопрос, как этот , поскольку суть вопроса отличается. Я пытаюсь перенаправить пользователей, которые пытаются получить доступ к сайту с помощью языкового кода (обычно en
или cz
), на index.php
с языком набор переменных. Сам сайт может распознавать только настройки английского и чешского языков, все остальные перенаправляются на основе геолокации IP посетителя (с использованием внешнего онлайн-API JSON). Но проблема в том, что этот браузер продолжает перенаправлять и выдает ошибку, что произошло слишком много перенаправлений. Что случилось? Пытался найти ошибку, но ничего не обнаружил.
Это полный .htaccess
файл:
Options -Indexes
RewriteEngine on
RewriteRule ^[a-z]{2,3}/$ /index.php?lang=$1
RewriteRule ^blog/?(.*)$ //blog.czghost.czlh/$1 [R=301]
RewriteRule ^ftp/?(.*)$ //ftp.czghost.czlh/$1 [R=301]
Кроме того, если пользователь пишет в index.php? Lang = $ 1
, мне нужно вместо этого перенаправить его на хороший вариант URL. Я искал в Интернете, но мне это кажется слишком сложным: (
Я тестирую сайты на своем сервере WAMP на моем компьютере с Windows, прежде чем он будет готов к развертыванию в Интернете.
Вы на самом деле не указали запрашиваемые URL-адреса, запускающие цикл перенаправления?
Однако из опубликованных вами директив может показаться, что любой запрос формы / blog
или / ftp
приведет к циклу перенаправления.
RewriteRule ^ blog /?(.*)$ // blog.czghost.czlh / 1 доллар США [R = 301] RewriteRule ^ ftp /?(.*)$ //ftp.czghost.czlh/$1 [R = 301]
Apache mod_rewrite не поддерживает зависящие от протокола URL-адреса в подстановке RewriteRule
- они просто рассматриваются как относительные к корню (т. Е. URL-путь относительно корня документа). Вы, вероятно, видите результат этого цикла перенаправления в адресной строке своего браузера?Это будет примерно так:
http://example.com/blog/xyz
http://example.com//blog.czghost.czlh/ xyz
http://example.com//blog.czghost.czlh/.czghost.czlh/xyz
http://example.com//blog.czghost .czlh / .czghost.czlh / .czghost.czlh / xyz
Вам необходимо включить протокол. Например:
RewriteRule ^blog/?(.*)$ https://blog.czghost.czlh/$1 [R=301,L]
Я также включил флаг L
( last
), так как вы хотите, чтобы перенаправление запускалось немедленно, не подвергаясь риску дальнейшей перезаписи. Это действительно должно произойти до внутренней перезаписи (которая переписывает в index.php
).
Вам нужно будет убедиться, что вы очистили кеш браузера, так как ошибочный 301 ( постоянный ]) перенаправление будет кешировано браузером. По этой причине может быть проще протестировать с 302 (временными) перенаправлениями.
Правила вашего блога
и ftp
могут обрабатываться одной директивой, используя чередование . Например:
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
RewriteRule ^ [a-z] {2,3} / $ /index.php?lang=$1
В шаблоне RewriteRule
нет группы захвата (т. Е. Заключенного в скобки подшаблона), поэтому обратная ссылка $ 1
всегда будет пустой. Это должно быть переписано как:
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]
Опять же, я включил флаг L
, чтобы предотвратить дальнейшую перезапись. Обратите внимание, что ожидается, что в конце пути URL будет суффикс косой черты. Таким образом, только URL-адреса вида / blog / en /
(с суффиксом косой черты) будут успешно переписаны (хотя, возможно, это не имеет отношения к этому).
Итак, в целом, это следует переписать примерно так :
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]
Кроме того, если пользователь пишет в
index.php? Lang = $ 1
, мне нужно вместо этого перенаправить его на удобный вариант URL.
Вы можете сделать это с помощью дополнительного перенаправления до вышеуказанных директив. Например:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^lang=([a-z]{2,3})$
RewriteRule ^(index\.php)?$ /%1/? [R=301,L]
Вам необходимо использовать директиву RewriteCond
, чтобы проверить строку запроса на соответствие серверной переменной QUERY_STRING
(это невозможно сделать в RewriteRule
] директива). Предыдущая проверка переменной среды REDIRECT_STATUS
должна гарантировать, что мы обрабатываем только начальные запросы, а не перезаписываем запросы более поздней директивой, которая переписывает URL-адрес на /index.php?lang=xyz
. Переменная окружения REDIRECT_STATUS
пуста при начальном запросе, но получает значение «200» (как в 200 OK - статус HTTP) после первой успешной перезаписи .
Это будет соответствует либо index.php
, либо пустому пути URL (например, /? lang = xyz
). % 1
- это обратная ссылка на последний совпавший CondPattern (в отличие от $ N
, который является обратной ссылкой на шаблон RewriteRule
]). ?
в конце подстановки RewriteRule
необходим для удаления строки запроса из перенаправленного URL-адреса (в качестве альтернативы можно использовать QSD
flag на Apache 2.4 +).
Опять же, лучше сначала протестировать с 302 (временным) перенаправлением, которое не будет кэшироваться браузером.
(Из комментариев:) Единственное, что работает правильно , это перенаправление
/ ftp /
./ blog /
перенаправление остается с неизмененным URL-адресом на пустой странице
Вы должны убедиться, что в файловой системе нет физического каталога с тем же именем, т.е. / блог
. И что в этом подкаталоге нет дополнительного файла .htaccess
, который мог бы его переопределить. Также убедитесь, что нет файла с тем же базовым именем blog
. например. blog.html
или blog.php
и т. Д. Если есть, то вам нужно убедиться, что MultiViews (часть mod_negotiation) не включен. т.е. Параметры -Индексы -MultiViews
. Если MultiViews включен, Apache выполнит внутренний подзапрос для /blog.php
(например), прежде чем mod_rewrite сможет перезаписать URL.
Options -Indexes -MultiViews
RewriteEngine on
# Redirect direct requests for "index.php?lang=xyz" to "/xyz/"
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^lang=([a-z]{2,3})$
RewriteRule ^(index\.php)?$ /%1/? [R=301,L]
# Redirect "blog" or "ftp/<anything>" to subdomain
RewriteRule ^(blog|ftp)/?(.*)$ https://$1.czghost.czlh/$2 [R=301,L]
# Internally rewrite "/xyz/" to "/index.php?lang=xyz"
RewriteRule ^([a-z]{2,3})/$ /index.php?lang=$1 [L]