Мне просто интересно, правильно ли у меня структура 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
. Вроде все работает нормально. У меня есть два вопроса:
<ifmodule>
блок? 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-адресом запроса, так что здесь все в порядке).
- Если
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
директива.)