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

Как мне избежать ошибки в этом файле .htaccess?

У меня есть блог. Блог хранится под /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 доступны и использовать ссылка каноническая (не самый лучший, но простой)
  • Если серверный сценарий (PHP возможно) доступен, перенаправить /blog/index.php к / на уровне сценария