Я хочу сделать следующее перенаправление:
Я использую следующие команды в моем 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 (и пользователей) вам, вероятно, не следует вообще перенаправлять и просто позволить пользователю решать - возможно рекомендуя языковая версия, основанная на предполагаемых языковых предпочтениях. Помимо «ненадежности» (как отмечалось выше), если вы принудительно перенаправляете, поисковые системы, вероятно, когда-либо увидят только одну версию. Для поисковых систем убедитесь, что у вас есть подходящие <link HREFLANG>
элементы. См. Также документы справки Google: Управление многорегиональными и многоязычными сайтами
перечислены файлы в корневой папке.
В стороне: Если файлы перечисленные тогда похоже, что вам нужно отключить индексы каталогов. Либо удалите Indexes
вариант из основного Options
директиве или отключите параметр на виртуальном хосте:
Options -Indexes
ОБНОВЛЕНИЕ №1: Проблема, которая не сразу очевидна из вашего вопроса, заключается в том, что вы получаете другой ответ от HTTP, чем от HTTPS. Кажется, что HTTP-запрос работает "ОК" (после удаления RewriteCond
директиве выше), но это запрос HTTPS, который не работает должным образом. Фактически, запрашивая https://example.net/
похоже, полностью обходит ваши директивы.
Эта разница между HTTP и HTTPS подразумевает, что директивы находятся в неправильном месте в конфигурации вашего сервера, поскольку запросы HTTP и HTTPS обычно обрабатываются разными виртуальными хостами. Посмотрев на ваши файлы конфигурации, это действительно кажется проблемой.
У вас есть 2 <VirtualHost>
контейнеры, один для порта 80 (HTTP), а другой для порта 443 (HTTPS). Указанные выше директивы mod_rewrite находятся только в вашем виртуальном хосте порта 80, поэтому они применяются только к HTTP-запросам, а не HTTPS.
Я предполагаю, что вы хотите канонизировать запрос, чтобы все HTTP-запросы перенаправлялись на HTTPS.
Вам необходимо сделать следующее:
<VirtualHost X.X.X.X:80>
контейнер и положить их в <VirtualHost X.X.X.X:443>
вместо. Вам не нужен <IfModule mod_rewrite.c>
обертка.в <VirtualHost X.X.X.X:80>
контейнер (который ранее содержал указанные выше директивы) выдает перенаправление HTTP на HTTPS с использованием псевдонима мода Redirect
:
Redirect 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]
Однако это все же чрезмерное упрощение.
- Исходники из подкаталогов сейчас не загружаются (например,
<link rel="stylesheet" type="text/css" href="../indikatrix.css"/>
), в чем может быть причина? (если файл в корне)
Поскольку указанные выше директивы перенаправляют все либо к /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]