Я хотел бы сделать следующее перенаправление:
Я использую следующие команды в моем Apache conf:
RewriteCond %{REQUEST_URI} !^[^.]*/$
RewriteCond %{HTTP:Accept-Language} (hu) [NC]
RewriteRule ^(.*)$ https://example.net/hu [L]
RewriteCond %{HTTP:Accept-Language} (!hu) [NC]
RewriteRule ^(.*)$ https://example.net/en [L]
Проблема в том, что я запрашиваю только https://example.net
, перенаправления нет, перечислены только файлы в корневой папке.
РЕДАКТИРОВАТЬ: текущие правила перезаписи:
<IfModule mod_rewrite.c>
RewriteEngine On
# This will enable the Rewrite capabilities
RewriteCond %{HTTP:Accept-Language} hu [NC]
RewriteRule !^/?hu https://example.net/hu [L]
RewriteCond %{HTTP:Accept-Language} !hu [NC]
RewriteRule !^/?en https://example.net/en [L]
</IfModule>
RewriteCond% {REQUEST_URI}! ^ [^.] * / $
Это условие предотвратит «перенаправление» запросов на корень документа. (Не совсем уверены, в чем заключается идея этой директивы?)
Вам также следует изменить шаблоны RewriteRule
, чтобы исключить / hu
и / en
соответственно, чтобы избежать ненужного (дополнительного) цикла. Например:
RewriteCond %{HTTP:Accept-Language} hu [NC]
RewriteRule !^/?hu https://example.net/hu/ [R,L]
RewriteCond %{HTTP:Accept-Language} !hu [NC]
RewriteRule !^/?en https://example.net/en/ [R,L]
Обратите внимание, что, поскольку / hu
и / en
являются физическими каталогами, вам следует включить в конечный URL-адрес косую черту. В противном случае mod_dir выполнит второе перенаправление 301, чтобы добавить завершающую косую черту.
Однако эта логика ошибочна. Заголовок Accept-Language
может содержать несколько языков. И каждый язык может быть «взвешен», указывая предпочтения пользователей. Согласно вашей логике, венгерский сайт будет отображаться для пользователя, который принимает венгерский язык, но предпочитает английский. Упрощенное решение состоит в том, чтобы предположить , что предпочтительным языком является первый заявленный язык, в этом случае измените CondPatterns на ^ hu
и ! ^ hu
соответственно. Однако это не обязательно будет надежным во всех случаях.
И ... для SEO (и пользователей) вам, вероятно, не следует перенаправлять вообще и просто позволить пользователю решать - возможно, рекомендуя языковая версия, основанная на предполагаемых языковых предпочтениях. Помимо "ненадежности" (как отмечалось выше), если вы принудительно перенаправляете, поисковые системы, вероятно, когда-либо увидят только одну версию. Что касается поисковых систем, убедитесь, что у вас есть соответствующие элементы
. См. Также справочную документацию Google: Управление многорегиональными и многоязычными сайтами Перечислены
файлы в корневой папке.
Кроме того: Если файлы перечислены , то это звучит например, вам нужно отключить индексы каталогов. Либо удалите параметр Индексы
из основной директивы Параметры
, либо отключите параметр на виртуальном хосте:
Options -Indexes
ОБНОВЛЕНИЕ №1: Проблема, которая не сразу очевидна из ваш вопрос в том, что вы получаете другой ответ от HTTP, чем от HTTPS. Кажется, что HTTP-запрос работает "нормально" (после удаления директивы RewriteCond
выше), но это HTTPS-запрос, который не работает должным образом. Фактически, запрос https://example.net/
, похоже, полностью обходит ваши директивы.
Эта разница между HTTP и HTTPS подразумевает, что директивы находятся не в том месте в конфигурации вашего сервера, поскольку HTTP и HTTPS-запросы обычно обрабатываются разными виртуальными хостами. Если посмотреть на ваши файлы конфигурации, это действительно кажется проблемой.
У вас есть 2
контейнера, один для порта 80 (HTTP), а другой - для порта 443 (HTTPS). Указанные выше директивы mod_rewrite есть только в вашем vhost порта 80, поэтому они применяются только к HTTP-запросам, а не по HTTPS.
Я предполагаю, что вы хотите канонизировать запрос, чтобы все HTTP-запросы перенаправлялись на HTTPS.
Вам необходимо сделать следующее:
и поместите их в
. Вам не нужна оболочка
. В контейнере
(который ранее содержал указанные выше директивы) отправьте HTTP для Перенаправление HTTPS с использованием псевдонима мода Перенаправление
:
Перенаправление 301 / https://example.net/
Однако, если у вас есть планы по реализации HSTS , вам следует вместо этого использовать здесь mod_rewrite (для перенаправления на тот же хост):
RewriteRule ^ https: //% {HTTP_HOST}% {REQUEST_URI } [R = 301, L]
(Или ... вам нужно будет разделить каждый из ваших текущих vhosts на версии с www и без www, вместо того, чтобы иметь только два vhosts, каждый из которых охватывает www и не www.)
Итак, вы закончили примерно таким:
<VirtualHost X.X.X.X:80>
ServerName example.net
ServerAlias www.example.net
ServerAdmin webmaster@example.net
DocumentRoot /home/example/public_html/
### OTHER DIRECTIVES HERE... ###
# Redirect all requests to HTTP
Redirect 301 / https://example.net/
### OTHER DIRECTIVES HERE... ###
</VirtualHost>
<VirtualHost X.X.X.X:443>
ServerName example.net
ServerAlias www.example.net
ServerAdmin webmaster@example.net
DocumentRoot /home/example/public_html/
### OTHER DIRECTIVES HERE... ###
RewriteEngine on
# Language redirect...
RewriteCond %{HTTP:Accept-Language} hu [NC]
RewriteRule !^/?hu https://example.net/hu/ [R,L]
RewriteCond %{HTTP:Accept-Language} !hu [NC]
RewriteRule !^/?en https://example.net/en/ [R,L]
SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/indikatrix.net.cert
SSLCertificateKeyFile /etc/pki/tls/private/indikatrix.net.key
SSLCertificateChainFile /etc/pki/tls/certs/indikatrix.net.bundle
SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
### OTHER DIRECTIVES HERE... ###
</VirtualHost>
Однако также обратите внимание на мои комментарии выше о потенциально ошибочной логике и подумайте об изменении регулярного выражения в вышеуказанных директивах соответственно.
Кроме того, что не охвачено вышеизложенным (и не рассматривается в вашем вопросе), это то, что должно произойти с запросом, таким как https://example.net/foo/bar
? В настоящее время выполняется перенаправление на https://example.net/hu/
(или / en /
). Если это не перенаправляет на / hu / foo / bar
(или / en / foo / bar
)?
ОБНОВЛЕНИЕ № 2:
- Почему у меня загружается страница
/ hu
, если язык моих браузеров английский?
Потому что я подозреваю, что ваша машина также поддерживает "венгерский". Это проблема вышеупомянутой «логики» (как упоминалось ранее). Заголовок запроса Accept-Language
более сложен, он содержит строку вида:
en-GB,en;q=0.9,hu;q=0.8,id;q=0.7,en-US;q=0.6
Даже если венгерский не является основным языком, если он установлен, то в заголовке содержится «hu». Возможно, вы можете изменить регулярное выражение так, чтобы оно соответствовало hu
в начале строки (а не где угодно ) - как упоминалось выше. Например:
RewriteCond %{HTTP:Accept-Language} ^hu [NC]
RewriteRule !^/?hu https://example.net/hu/ [R,L]
RewriteCond %{HTTP:Accept-Language} !^hu [NC]
RewriteRule !^/?en https://example.net/en/ [R,L]
Однако это все еще чрезмерное упрощение.
- Источники из подкаталогов сейчас не загружаются (например,
), в чем может быть причина? (если файл находится в корневом каталоге)
Потому что вышеуказанные директивы перенаправляют все либо в подкаталог / hu
, либо / en
. Вам необходимо изменить указанные выше директивы, чтобы запросы на существующие файлы игнорировались. Если у вас нет других директив, которые необходимо обработать (в данный момент у вас их нет), вы можете сделать это за один раз перед существующими директивами:
RewriteCond %{LA-U:REQUEST_FILENAME} -f
RewriteRule ^ - [L]
Если запрос сопоставляется с существующим файлом, обработка останавливается . Вы можете оптимизировать это так, чтобы он был нацелен только на CSS, JS и изображения (имейте в виду, что это означает, что CSS, JS и изображения никогда не будут перенаправлены):
RewriteCond %{LA-U:REQUEST_FILENAME} -f
RewriteRule \.(css|js|jpg|png|gif)$ - [NC,L]
Вам следует избегать использования относительных путей к вашему статические ресурсы, чтобы избежать проблем в будущем, если вы решите переписать URL. Таким образом, вместо ссылки на файл CSS в корне документа с использованием относительного URL-пути, такого как ../ indikatrix.css
, используйте вместо этого относительный путь к корню: /indikatrix.css
.
ОБНОВЛЕНИЕ № 3:
, если я хочу загрузить:
https://example.net/hu
, затемhttps://example.net/en
принудительно .
Если вы хотите иметь возможность переопределить перенаправление (на основе заголовка Accept-Lanaguage
), измените шаблон RewriteRule
на ! ^ / (en | hu)
для обоих правил.
Options -Indexes -MultiViews
RewriteEngine On
RewriteCond %{LA-U:REQUEST_FILENAME} -f
RewriteRule \.(css|js|jpg|png|gif)$ - [NC,L]
RewriteCond %{HTTP:Accept-Language} ^hu [NC]
RewriteRule !^/(en|hu) https://example.net/hu/ [R,L]
RewriteCond %{HTTP:Accept-Language} !^hu [NC]
RewriteRule !^/(en|hu) https://example.net/en/ [R,L]