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

Автоматическое перенаправление в подкаталог, а также удаление www

Я хочу сделать 2 вещи: перенаправить http://www.example.com (с участием www) к http://example.com/fr (без www, И подкаталог)

Конечно я тоже хочу http://example.com перенаправить на http://example.com/fr.

Я видел это решение:

RewriteCond %{HTTP_HOST} ^(www\.)?example.com$ [NC]
RewriteCond %{REQUEST_URI} !^/fr/.*$
RewriteRule ^(.*)$ /fr/$1 [L,R=301,NC]

Но это как сумасшедшее тормозит мой сайт (потом невозможно загрузить страницу) .. Что я должен исправить в приведенном выше коде?

Вот мой полный код

Options +FollowSymLinks
RewriteEngine on

RewriteBase /
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^index\.php$ - [L]

RewriteCond %{HTTP_HOST} ^(www\.)?beastof\.com$ [NC]
RewriteCond %{REQUEST_URI} /(.*)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^fr(/|$) /fr/%1 [R=301,L]

RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]

(Это мультисайт WordPress в подкаталогах.)

RewriteCond %{HTTP_HOST} ^(www\.)?example.com$ [NC]
RewriteCond %{REQUEST_URI} !^/fr/.*$
RewriteRule ^(.*)$ /fr/$1 [L,R=301,NC]

Эти директивы не просто перенаправляют "http://www.example.com к http://example.com/fr". Они перенаправляют http://www.example.com/<anything> к http://www.example.com/fr/<anything>.

Но это сильно тормозит мой сайт ...

В опубликованных вами директивах нет ничего особенно плохого, но ...

Я предполагаю, что вы ссылаетесь на другие страницы / ресурсы без /fr/ сегмент пути. Это затем приводит к множеству внешних перенаправлений для каждого просмотра страницы - это потенциально может замедлить работу вашего сайта (хотя это 301 редирект, поэтому браузер должен кэшировать их).

Если это так, то вам нужно либо исправить свои внутренние ссылки, чтобы включить этот /fr/ сегмент пути. Или, возможно, исключите статические ресурсы из этого перенаправления (если URL-адрес все еще действителен без /fr/ отрезок пути)?

Например, чтобы исключить все статические ресурсы, измените свои директивы, например:

RewriteCond %{HTTP_HOST} ^(www\.)?example\.com$ [NC]
RewriteCond %{REQUEST_URI} /(.*)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^fr/ /fr/%1 [R=301,L]

Теперь это предотвратит перенаправление статических ресурсов (физических файлов) (я не знаю, действительно ли это по-прежнему).

Я также немного оптимизировал ваши директивы (впрочем, ничего, что могло бы значительно ускорить работу). Я переместил отрицательный чек на /fr/ к RewriteRule шаблон, а не использовать RewriteCond директива для этого. В RewriteRule шаблон обрабатывается первой, поэтому лучше включить сюда вашу первую проверку, если вы можете (в противном случае каждый URL будет обработан). Затем URL-адрес берется из состояние вместо этого (%1 вместо того $1 обратная ссылка в RewriteRule замена). Нет необходимости использовать NC (NOCASE), если он явно не нужен.


ОБНОВЛЕНИЕ №1:

example.com/fr (без косой черты в конце), [...] перенаправляет на example.com/fr/fr

Чтобы решить эту проблему, вы можете изменить RewriteRule шаблон исключить точное совпадение для /fr или URL, который начинается /fr/, например:

RewriteRule !^fr(/|$) /fr/%1 [R=301,L]

Теперь это предотвратит example.com/fr от перенаправления. (Однако это действительный URL-адрес? Теперь у вас есть два URL-адреса: example.com/fr и example.com/fr/ предположительно доступ к тому же ресурсу?)

Вот мой полный код

:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
:

Поскольку вы добавили свой «полный код» в свой вопрос, я вижу, что у вас уже есть блок «исключения» (3 директивы выше), который исключает переписывание статических ресурсов - просто он находится не в том месте, теперь, когда вы Мы добавили дополнительные директивы выше.

Вы должны переместить эти 3 директивы непосредственно под RewriteBase директива (т.е. вверху). Хотя вам нужно исключить корень документа от этого (изменив ^ к !^$ - см. ниже), чтобы / быть перенаправленным на /fr/ - поскольку корень документа также является каталогом. Затем вы можете удалить RewriteCond %{REQUEST_FILENAME} !-f директива из блока выше (в первой части этого ответа).


ОБНОВЛЕНИЕ # 2 Итак, в итоге ...

(Обновлено, чтобы включить в начале каноническое перенаправление с www на не-www. Это затем позволяет нам упростить последующее условие, которое проверяет HTTP_HOST.)

Options +FollowSymLinks
RewriteEngine on

RewriteBase /

# Canonical www to non-www redirect
RewriteCond %{HTTP_HOST} ^www\.(example\.com)$ [NC]
RewriteRule (.*) http://%1/$1 [R=301,L]

# Exception: Exclude files and directories (except the document root)
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule !^$ - [L]

RewriteRule ^index\.php$ - [L]

# Redirect all requests to /fr/ subdirectory
RewriteCond %{HTTP_HOST} =example.com [NC]
RewriteCond %{REQUEST_URI} /(.*)
RewriteRule !^fr(/|$) /fr/%1 [R=301,L]

RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]