Чтобы прояснить ситуацию, это НЕ повторяющийся вопрос, например вот этот поскольку суть вопроса в другом. Я пытаюсь перенаправить пользователей, которые пытаются получить доступ к сайту, используя языковой код (обычно 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<anything>
или /ftp<anything>
приведет к возникновению цикла перенаправления.
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 (временными) перенаправлениями.
Ваш blog
и 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
env var пуст при первоначальном запросе, но получает значение "200" (как в 200 OK - статус HTTP) после первого успешного переписать.
Это будет соответствовать либо index.php
или пустой путь URL (например, /?lang=xyz
). %1
это обратная ссылка на последнее совпадение CondPattern (в отличие от $N
это обратная ссылка на RewriteRule
шаблон). В ?
в конце RewriteRule
замена необходимо, чтобы удалить строку запроса из перенаправленного URL-адреса (в качестве альтернативы вы можете использовать QSD
флаг на Apache 2.4+).
Опять же, лучше всего сначала протестировать с 302 (временным) перенаправлением, которое не будет кэшироваться браузером.
(Из комментариев :) Единственное, что работает правильно, это
/ftp/
перенаправить./blog/
перенаправление остается с неизменным URL-адресом на пустой странице
Вы должны убедиться, что в файловой системе нет физического каталога с тем же именем, т.е. /blog
. И что в этом подкаталоге нет дополнительных .htaccess
файл, который может переопределить это. Также убедитесь, что нет файл с таким же базовым именем blog
. например. blog.html
или blog.php
и т.д. Если есть, то вам нужно убедиться, что MultiViews (часть mod_negotiation) не включен. т.е. Options -Indexes -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]