2013-05-22 2 views
0

У меня есть файл .htaccess, как это:Порядок правил в файле .htaccess

RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^foo.*$ /cgi/foo.cgi [L] 
RewriteRule ^.*$ /cgi/fallback.cgi [L] 

, но когда я иду в URL, начиная с обув в этой папке, браузер все еще перенаправляется на fallback.cgi сценария. Если я удалю второе правило, линия «foo» работает нормально.

Согласно моему пониманию, первое правило должно иметь приоритет, а [L] должно предотвращать любые другие правила.

ответ

2

Вы Правильно, первое правило должно применяться сначала, и я думаю, что это так. Проблема может быть второе правило также применяется, так что код должен быть таким:

RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^foo.*$ /cgi/foo.cgi [L,NC] 

RewriteCond %{REQUEST_URI} !/cgi/(foo|fallback)\.cgi [NC] 
RewriteCond %{REQUEST_URI} !/foo [NC] 
RewriteRule ^.*$ /cgi/fallback.cgi [L] 
+0

Если применяется второе правило, какова точка флага [L]? – AmbroseChapel

+1

Флаг [L] не останавливает процесс. Проверьте [технические детали] (http://httpd.apache.org/docs/2.2/rewrite/tech.html) –

+0

Узнали что-то новое. Это определенно противоречит интуиции о том, как они обрабатывают правила и условия. +1 –

1

^ означает начало строки.

RewriteRule ^foo.*$ /cgi/foo.cgi [L] 

Так что правила ТОЛЬКО соответствуют/foo, за которыми следуют ноль или более символов.

Чтобы соответствовать файл, начиная с использования "Foo" это:

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

Это соответствует:

/foo 
/foo.php 
/food.php 
/foolish/dog 

Это не соответствует:

/kung-foo.cat 
/FOO.php 

Update Запомнить что некоторые браузеры перенаправляют кеширование. Я тестировал это на своем собственном сервере и выполнял перенаправление, которое было кэшировано. Меня немного смутило, когда мои новые правила не работали.

+0

Спасибо за это, но в данном случае я могу заверить вас, что нет чувствительности к регистру, и нет никаких сомнений в том, что путь начинается с 'foo'. Об этом свидетельствует тот факт, что он работает так, как ожидается, когда второй из двух правил будет удален. – AmbroseChapel

1

Он применяет второе правило, потому что;

  1. Во 2-ом правиле Ваш, соответствие .* (значит все)
  2. RewriteCond линии только применяется к 1-ому правилу только

Правильный код будет:

Options +FollowSymLinks -MultiViews 
# Turn mod_rewrite on 
RewriteEngine On 
RewriteBase/

# don't do anything for a file, dir or symlnk 
RewriteCond %{REQUEST_FILENAME} !-f [OR] 
RewriteCond %{REQUEST_FILENAME} !-d [OR] 
RewriteCond %{REQUEST_FILENAME} !-l 
RewriteRule^- [L] 

RewriteRule (^|/)foo /cgi/foo.cgi [L,NC] 

RewriteRule^/cgi/fallback.cgi [L] 
+0

«Линии RewriteCond применяются только к 1-му правлению» - я не понимаю. Даже если они применяются к первому правилу, то первое правило правильно соответствует и имеет флаг [L], поэтому второе правило никогда не должно срабатывать. – AmbroseChapel

+0

2-е правило срабатывает после завершения 1-го правила. Apache будет продолжать применять все правила, если они удовлетворяют условиям. – anubhava

Смежные вопросы