У меня есть блог. Блог хранится под /blog/
префикс на моем сайте. У него обычные URL-адреса для блога, поэтому статьи имеют URL-адреса в формате /blog/:year/:month/:day/:title/
.
Прежде всего, я хочу автоматически перенаправлять посетителей на www
поддомен (в случае, если они его не отключат), и внутри перепишите корневой URL на /blog/
, чтобы первая страница блога отображалась на первой странице сайта. Я добился этого с помощью следующего набора правил перезаписи в моем .htaccess
файл:
RewriteEngine On
# Rewrite monkey-robot.com to www.monkey-robot.com
RewriteCond %{HTTP_HOST} ^monkey-robot\.com$
RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L]
RewriteRule ^$ /blog/ [L]
RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]
Это нормально работает. Проблема в том, что теперь первая страница блога отображается по двум отдельным URL-адресам: /
и /blog/
. Так что я бы хотел перенаправить в /blog/
URL-адрес корневого URL-адреса. Изначально я пытался добиться этого с помощью следующего набора правил перезаписи:
RewriteEngine On
# Rewrite monkey-robot.com to www.monkey-robot.com
RewriteCond %{HTTP_HOST} ^monkey-robot\.com$
RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L]
RewriteRule ^$ /blog/ [L]
RewriteRule ^blog/?$ / [R,L]
RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]
Но это дало мне бесконечное перенаправление (может быть, из-за предыдущего правила?). Итак, я попробовал этот набор:
RewriteEngine On
# Rewrite monkey-robot.com to www.monkey-robot.com
RewriteCond %{HTTP_HOST} ^monkey-robot\.com$
RewriteRule ^(.*)$ http://www.monkey-robot.com/$1 [R=301,L]
RewriteRule ^$ /blog/ [L]
RewriteRule ^blog/?$ http://www.monkey-robot.com/ [R,L]
RewriteRule ^feeds/blog/?$ /feeds/blog/atom.xml [L]
Но я получил 500 Internal Server Error со следующим сообщением журнала:
Неверная команда "[R, L]", возможно, написана с ошибкой или определена модулем, не включенным в конфигурацию сервера.
Что дает? Я не думаю [R,L]
это синтаксическая ошибка.
Я подозреваю, что вы могли бы избежать бесконечного цикла во втором наборе правил, поместив директивы перезаписи в основную конфигурацию виртуального хоста, а не в .htaccess
файл. В любом случае это хорошая практика, поскольку перезапись выполняется намного быстрее, когда вы помещаете ее на виртуальный хост, и вы можете получить дополнительные преимущества в скорости, если скажете Apache игнорировать .htaccess
файлы вместе.
Логика этого объяснена в mod_rewrite техническая документация. Вот суть: как вы знаете, правила перезаписи могут изменить имя файла, которому соответствует данный запрос, и даже каталог, в котором находится получившийся файл. Фактически, ваш
RewriteRule ^$ /blog/
отличный пример, который меняет корень документа на blog
каталог. Но Apache необходимо знать каталог, чтобы выяснить, какой .htaccess
файлы для проверки запроса. Возможно, вы видите проблему здесь: к тому времени, когда Apache достигнет вашего .htaccess
файл, у него есть уже определил имя файла, к которому он должен получить доступ, а это значит, что уже слишком поздно для применения ваших правил перезаписи.
Apache внутренне решает эту проблему, создавая новый подзапрос, который начинает обработку с самого начала, и вводит правила из вашего .htaccess
файл в поток обработки, чтобы они применялись к запросу. Как побочный эффект этого, все применяются применимые правила перезаписи очередной раз, а это означает, что [L]
флаг - это своего рода ложь, когда вы используете его в .htaccess
файл. Итак, даже если вы положили [L]
о вашем правиле, чтобы попытаться заставить его быть последним применяемым правилом, на самом деле это не так; все правила применяются снова, когда Apache обрабатывает свой внутренний подзапрос.
Если у вас нет доступа к основной конфигурации сервера, вы можете сделать это:
RewriteRule ^/blog/?$ / [R,L,NS]
В NS
флаг предотвращает применение правила к подзапросам.
Прочитав комментарии, я думаю, что самым простым решением является перепишите корневую страницу в фактический файл (index.html
, Я полагаю?).
RewriteRule ^blog/$ / [R,L]
RewriteRule ^$ /blog/index.html [L]
Таким образом можно избежать зацикливания. Однако остается одна проблема - /blog/index.html
все еще доступный извне. Если это не вариант, я думаю, вам лучше всего следовать Дэвидсовет и перемещение конфигурации на один уровень вверх.
Некоторые альтернативы что пришло мне в голову:
/blog/index.html
доступны и использовать ссылка каноническая (не самый лучший, но простой)/blog/index.php
к /
на уровне сценария