mod_rewrite в <Location /> в apache conf, вызывающий перезапись в файле .htaccess, не работает? - PullRequest
3 голосов
/ 13 июля 2011

Я использую Zend Framework, в котором есть отличный пример .htaccess, используемый для перенаправления несуществующих расположений в index.php для обработки каркасом:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /site/index.php [NC,L]

А вот конфиг apache для / site

Alias /site "/path/to/zf/project/public"
<Directory "/path/to/zf/project/public">
    Options Indexes MultiViews FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

Во время обновления сайта я хочу перенаправить весь трафик в определенный файл (например, offline.html), за исключением определенного IP-адреса (например, 127.0.0.1), поэтому я пытаюсь использовать это правило в конфиге apache:

<Location />
    Options Indexes MultiViews FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from all

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1
    RewriteCond %{REQUEST_URI} !/offline\.html$
    RewriteRule .* /offline.html [R=302,L]
</Location>

Кажется, это работает, но по какой-то причине мой файл .htaccess кажется не работает. Я могу получить доступ к / site просто отлично, но не могу углубиться, например, в /site/controller/action.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 13 июля 2011

Документация Apache 2.2 и Apache 2.4 для mod_rewrite четко гласит, что следует избегать правил перезаписи в директивах <Location>. Это предупреждение не было включено в документацию Apache 2.0 .

Хотя правила перезаписи синтаксически разрешены в разделах <Location> и <Files> (включая их аналоги из регулярных выражений), это никогда не должно быть необходимым и не поддерживается. Вероятная особенность в этих контекстах - относительные замены.

Так могут происходить странные вещи. Вы можете удалить раздел <Location> (и директиву RewriteBase) и использовать эти новые правила перезаписи непосредственно в определении <VirtualHost>, без раздела <Directory> или <Location>. Это даже быстрее.

Единственная проблема с правилами переписывания глобального уровня заключается в том, что у вас нет уже вычисленного REQUEST_FILENAME (вы могли бы его немного взломать, но здесь вам даже не нужно REQUEST_FILENAME).

У вас также есть одна ошибка в RewriteRule, вы используете Redirect, поэтому правило перезаписи должно использовать абсолютный URL :

RewriteRule .* http://www.example.com/offline.html [R=302,L]

О странице обслуживания, классический способ работы с ней заключается в следующих двух строках:

ErrorDocument 503 /htdocs/err/503.html
RedirectMatch 503 ^/(?!err/)

Если вы не выполняете фильтрацию по локальному IP, но интересная часть заключается в том, что для обслуживания используется код 503 (временно недоступен), что является более правильным (на самом деле перенаправление 307 еще более корректно, но старый браузер может иметь проблемы с Это). Чтобы сделать то же самое с локальным ограничением IP и RewriteRule, это будет:

ErrorDocument 503 /offline.html
RewriteCond %{REMOTE_HOST} !^127\.0\.0\.1
RewriteCond %{END:REDIRECT_STATUS} !=503
RewriteRule ^ - [L,R=503]
0 голосов
/ 13 июля 2011

Чтобы иметь эти правила в файле htaccess, вам придется добавлять / удалять их вручную, если вы хотите использовать «автономный режим».

Лучший способ сделать это через приложение - этосоздать плагин контроллера.Если APPLICATION_ENV = 'offline', плагин будет делать _forward('offline', 'error', 'default');

В качестве альтернативы, вы можете написать логику в подклассе Zend_Controller_Action, который вы используете в качестве базового класса для ваших контроллеров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...