Когда не следует использовать mod_rewrite
Этот документ дополняет mod_rewrite справочную документацию. В нём описывается, пожалуй, одно из важнейших понятий, связанных с mod_rewrite, а именно — когда его не следует использовать.
mod_rewrite следует рассматривать как крайнюю меру, когда другие варианты не подходят. Использование его при наличии более простых альтернатив приводит к конфигурациям, которые сложно понять, которые ненадёжны и трудны в сопровождении. Понимание доступных альтернатив — очень важный шаг к освоению mod_rewrite.
Обратите внимание, что многие из этих примеров не будут работать без изменений в вашей конкретной конфигурации сервера, поэтому важно понять их, а не просто копировать и вставлять в свою конфигурацию.
Наиболее распространённая ситуация, в которой mod_rewrite подходит лучше всего, — когда для оптимального решения требуется доступ к файлам конфигурации сервера, а у вас такого доступа нет. Некоторые директивы конфигурации доступны только в файле конфигурации сервера. Поэтому, если вы пользуетесь хостингом, где можете работать только с файлами .htaccess, возможно, вам придётся прибегнуть к mod_rewrite.
Простая переадресация
mod_alias предоставляет директивы Redirect и RedirectMatch, позволяющие перенаправить один URL на другой. Такое простое перенаправление одного URL или группы URL в другое место следует выполнять с помощью этих директив, а не RewriteRule. RedirectMatch позволяет использовать регулярное выражение в условиях перенаправления, предоставляя многие преимущества применения RewriteRule.
Часто RewriteRule используют для перенаправления целой группы URL. Например, все URL в каталоге /one необходимо перенаправить в http://one.example.com/ или, возможно, все запросы http необходимо перенаправить в https.
Такие ситуации лучше обрабатывать с помощью директивы Redirect. Помните, что Redirect сохраняет информацию о пути. Иными словами, перенаправление URL /one также перенаправит все URL, расположенные ниже него, например /one/two.html и /one/three/four.html.
Чтобы перенаправить URL в /one в http://one.example.com, выполните следующие действия:
Redirect "/one/" "http://one.example.com/"
Чтобы перенаправить одно имя хоста на другое, например example.com на www.example.com, см. пример Канонические имена хостов.
Чтобы перенаправить URL http в https, выполните следующие действия:
<VirtualHost *:80>
ServerName www.example.com
Redirect "/" "https://www.example.com/"
</VirtualHost>
<VirtualHost *:443>
ServerName www.example.com
# ... SSL configuration goes here
</VirtualHost> Использование RewriteRule для выполнения этой задачи может быть уместным, если в той же области действия заданы другие директивы RewriteRule. Это объясняется тем, что при наличии директив Redirect и RewriteRule в одной области действия директивы RewriteRule выполняются первыми, независимо от порядка их появления в файле конфигурации.
В случае перенаправления http-to-https использование RewriteRule будет уместным, если у вас нет доступа к главному файлу конфигурации сервера и эту задачу приходится выполнять в файле .htaccess.
Псевдонимы URL
Директива Alias сопоставляет URI с каталогом — обычно с каталогом за пределами вашего DocumentRoot. Хотя такое сопоставление можно выполнить с помощью mod_rewrite, предпочтительнее использовать Alias — это проще и производительнее.
Использование Alias
Alias "/cats" "/var/www/virtualhosts/felines/htdocs"
Использование mod_rewrite для выполнения такого сопоставления может быть уместным, если у вас нет доступа к файлам конфигурации сервера. Alias можно использовать только в контексте сервера или виртуального хоста, но не в файле .htaccess.
Символические ссылки — ещё один способ добиться того же результата, если на сервере включён Options FollowSymLinks.
Виртуальные хосты
Хотя виртуальные хосты можно обрабатывать с помощью mod_rewrite, это редко бывает правильным решением. Почти всегда лучше создавать отдельные блоки <VirtualHost>. Если у вас огромное количество виртуальных хостов, рассмотрите возможность использования mod_vhost_alias для их автоматического создания.
Такие модули, как mod_macro, также полезны для динамического создания большого количества виртуальных хостов.
Использование mod_rewrite для создания виртуальных хостов может быть уместным, если вы пользуетесь услугами хостинга, который не предоставляет доступ к файлам конфигурации сервера, и поэтому ограничены настройкой с помощью файлов .htaccess.
Дополнительные сведения о том, как это можно сделать, если такой подход всё же кажется подходящим, см. в документе Виртуальные хосты с помощью mod_rewrite.
Простое проксирование
RewriteRule предоставляет флаг [P] для передачи переписанных URI через mod_proxy.
RewriteRule "^/?images(.*)" "http://imageserver.local/images$1" [P]
Однако во многих случаях, когда сопоставление с шаблоном не требуется, как в приведённом выше примере, директива ProxyPass будет более подходящим решением. Пример можно записать так:
ProxyPass "/images/" "http://imageserver.local/images/"
Обратите внимание: независимо от того, используете ли вы RewriteRule или ProxyPass, вам всё равно понадобится директива ProxyPassReverse для обработки перенаправлений, отправленных сервером внутреннего уровня:
ProxyPassReverse "/images/" "http://imageserver.local/images/"
Вместо этого может потребоваться использовать RewriteRule, если в той же области действия действуют другие директивы RewriteRule, поскольку RewriteRule обычно вступает в силу раньше, чем ProxyPass, и поэтому может помешать выполнению вашей задачи.
Проверка переменных окружения
mod_rewrite часто используют для выполнения определённого действия в зависимости от наличия или отсутствия конкретной переменной окружения или заголовка запроса. Это можно сделать эффективнее с помощью директивы <If>.
Рассмотрим, например, распространённую ситуацию, когда RewriteRule используется для задания канонического имени хоста, например www.example.com вместо example.com. Это можно сделать с помощью директивы <If>, как показано ниже:
<If "req('Host') != 'www.example.com'">
Redirect "/" "http://www.example.com/"
</If> Этот приём можно использовать для выполнения действий на основе любого заголовка запроса, заголовка ответа или переменной окружения, заменяя mod_rewrite во многих распространённых случаях.
В частности, см. документацию по вычислению выражений, где приводится обзор типов выражений, которые можно использовать в разделах <If> и некоторых других директивах.
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/rewrite/avoid.html