Я хочу сделать 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]