Назад | Перейти на главную страницу

Перенаправить все на https-сайты для конкретных языков

Я хочу сделать следующее перенаправление:

Я использую следующие команды в моем 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.

Вам необходимо сделать следующее:

  1. Переместите указанные выше директивы из <VirtualHost X.X.X.X:80> контейнер и положить их в <VirtualHost X.X.X.X:443> вместо. Вам не нужен <IfModule mod_rewrite.c> обертка.
  2. в <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.)

Итак, вы получите что-то вроде следующего:

indikatrix.net.txt

<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>

indikatrix.net.ssl.txt

<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:

  1. Почему /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]

Однако это все же чрезмерное упрощение.

  1. Исходники из подкаталогов сейчас не загружаются (например, <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]