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

структура htaccess, что куда идет

Мне просто интересно, правильно ли у меня структура htaccess, я не могу найти много информации о где чтобы поместить вещи в файл htaccess, поэтому я просто собрал все это вместе. Но, не желая вставлять сюда весь htaccess, краткое изложение моего htaccess выглядит следующим образом:

Options +FollowSymlinks
RewriteEngine On

order allow,deny
deny from {IP}
allow from all

#Prevent directory listings
Options All -Indexes

# compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript

ErrorDocument 403 /foo/bar/403.html

<IfModule mod_rewrite.c>        
    RewriteEngine On

    RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
    RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ /index.php [L]

</IfModule>


# Redirects
RedirectMatch 301 (?i)^/some-fancy-url/?$ /foo/bar/page.php

Есть намного больше RedirectMatchтам, и RewriteCond. Вроде все работает нормально. У меня есть два вопроса:

  1. Что-нибудь еще нужно переместить внутрь <ifmodule> блок?
  2. Если RedirectMatcheбыть наверху?

Это зависит от вашего варианта использования. Файл .htaccess обрабатывается в том порядке, в котором вы пишете строки.

Пример:

Если ваши условия внутри <IfModule> соответствует запросу, RedirectMatch никогда не достигается, так как RewriteRule отмечен как [L], смысл Last.
Если вы хотите, чтобы правило RedirectMatch имело более высокий приоритет, вы должны поднять его. Если с приоритетом сейчас все в порядке, оставьте как есть.

Учитывая move inside the IfModule block:

В <IfModule> Директива проверяет, загружен ли данный модуль.

Плюс: если модуль по какой-то причине не загружен, Apache все равно запустится без ошибок.
Оборотная сторона: ваше приложение может не работать, потому что перезапись не работает.

Вы можете просто удалить <IfModule> директивы, поэтому вы обнаружите проблему с отсутствующим модулем сразу же при запуске Apache. Конечно, в этом случае ничего не получится, потому что Apache не запускается.

Вам решать, как вы хотите, чтобы сервер вел себя.

Перемещение AddOutputFilterByType (или другие) директивы внутри <IfModule mod_rewrite.c> не имеет никакого смысла, потому что они не зависят от этого модуля.
Было бы разумнее окружить их собственным модулем, mod_deflate:

<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
# ... and so on
</IfModule>

Единственное, что я бы изменил в вашем файле, - это опустить первый RewriteEngine On линия. Это нужно только один раз, и у вас уже есть правильно внутри вашего <IfModule> блок.

Порядок ваших директив выглядит нормально. Однако обычно не рекомендуется смешивать mod_rewrite (RewriteRule) и mod_alias (RedirectMatch) директивы в том же контексте. Пояснение ниже ...

В файлах конфигурации Apache различные модули Apache (mod_rewrite, mod_alias, mod_expires, mod_access_compat / mod_authz_host и т. Д.) Обрабатываются независимо, независимо от очевидного порядка директив в файле конфигурации. Но внутри каждого модуля директивы обычно обрабатываются сверху вниз (как и следовало ожидать).

Если все директивы обрабатывались сверху вниз, то ваш RedirectMatch директивы в конце могут никогда не быть обработаны, потому что "фронт-контроллер" mod_rewrite, который предшествует ему, перезаписывает все запросы для несуществующих файлов в index.php. Итак, mod_alias RedirectMatch директивы в конце только надежно обрабатывается, потому что модули выполняются независимо. Однако mod_rewrite все равно выполняется до mod_alias, поэтому запрос, возможно, переписывается на index.php до того, как произойдет перенаправление (RedirectMatch работает с исходным URL-адресом запроса, так что здесь все в порядке).

  1. Если RedirectMatchбыть наверху?

Было бы логичнее иметь внешние перенаправления до внутренних перезаписей (ваш фронт-контроллер mod_rewrite). Однако, поскольку вы используете mod_alias для своих перенаправлений, они все равно выполняются.

Однако, как упоминалось в моем первом абзаце, «обычно не рекомендуется смешивать mod_rewrite (RewriteRule) и mod_alias (RedirectMatch) директивы в том же контексте ". Это связано с тем, что вы можете столкнуться с неожиданными конфликтами. Это зависит от того, что именно вы делаете, но если у вас есть оба RewriteRule и RedirectMatch директивы, которые обе соответствуют запрошенному URL-адресу, тогда не обязательно очевидно, что будет выполнено (что независимый порядка директив). По этой причине было бы предпочтительнее преобразовать mod_alias RedirectMatch to mod_rewrite RewriteRule директивы. Если вы сделаете это, то RewriteRule директивы, очевидно, должны быть перед существующий контроллер шрифтов mod_rewrite, иначе они могут никогда не выполняться.

Что-нибудь еще нужно переместить внутрь <ifmodule> блок?

Вам на самом деле не нужно <IfModule> блокировать вообще здесь. Это требуется только в том случае, если ваше приложение разработано для работы без mod_rewrite. И я сомневаюсь, что это так. например. WordPress использует <IfModule> wrapper, потому что он может нормально работать и без mod_rewrite (вы просто не получите таких хороших "красивых" URL). Если вы используете <IfModule> wrapper и mod_rewrite не установлены, тогда это просто не работает. Удалить <IfModule> wrapper, и вы получите фатальную ошибку, которая возникает до запуска системы, и вы можете легко ее исправить!

Однако веская причина использовать <IfModule> блоки - это если у вас есть один модуль, который зависит от включения другого. например. Вы хотели установить Header (с mod_headers) при условии, что URL был переписан с использованием mod_rewrite. В этом случае вы можете включить Header директива внутри <IfModule mod_rewrite.c> обертка. Однако такие случаи довольно редки.


Что касается множественных RewriteEngine директивы. Как уже сказал Джеральд, вам нужен только один. Более логично разместить это в верхней части вашего файла (или один раз с блоком директив mod_rewrite - если они находятся в кратком блоке ниже по файлу).

Однако это пример того, как выполнение сверху вниз (внутри модуля) не работает (поэтому я сказал только "в общем-то обрабатывается сверху вниз "). Вы можете разместить RewriteEngine On директива везде в файле конфигурации, и он по-прежнему работает - вы можете поместить его в самый конец, если хотите (но это сбивает с толку)! Если у вас несколько RewriteEngine директивы, то последняя в файле побеждает и контролирует весь файл (когда я говорю «файл», строго говоря, я имею в виду «контекст»). Вы не можете включить / выключить mod_rewrite во всем файле. Он либо включен, либо выключен для всего файла. Это также означает, что вы можете быстро отключить все mod_rewrite, просто поместив один RewriteEngine Off в самой последней строке файла - вам не нужно комментировать директивы. (То же самое относится и к RewriteBase директива.)