RewriteCond в .htaccess с отрицательным условием регулярного выражения не работает?
Я пытаюсь предотвратить, в этом случае WordPress, переписывание определенных URL-адресов. В этом случае я пытаюсь помешать ему когда-либо обрабатывать запрос в каталоге uploads и вместо этого оставлять его на странице сервера 404. Поэтому я предполагаю, что это просто, как добавление правила:
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/
Это правило должно оцениваться как ложное и заставить цепочку правил терпеть неудачу для этих запросов, тем самым останавливая переписывание. Но нет... Возможно, мне нужно сопоставить обложку полной строки в моем выражении?
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/.*$
Нет, это тоже не так. Поэтому, почесывая голову, я делаю проверку здравомыслия. Возможно, что-то не так с фактическим рисунком. Поэтому я делаю простой тестовый пример.
RewriteCond %{REQUEST_URI} ^/xyz/$
В этом случае переписывание происходит тогда и только тогда, когда запрошенный URL-адрес/xyz/и показывает страницу сервера 404 для любой другой страницы. Это именно то, чего я ожидал. Поэтому я просто вставлю! для отрицания этого шаблона.
RewriteCond %{REQUEST_URI} !^/xyz/$
Теперь я ожидаю увидеть полную противоположность вышеуказанному условию. Переписывание не должно происходить для /xyz/, но для всех других возможных URL-адресов. Вместо этого переписывание происходит для каждого URL-адреса, как /xyz/, так и других.
Итак, либо использование отрицаемых регулярных выражений в RewriteConds нарушено в Apache, либо есть что-то фундаментальное, о котором я не понимаю. Кто из них?
Сервер Apache2.
Файл целиком:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/
RewriteRule . /index.php [L]
</IfModule>
Файл по умолчанию WordPress плюс мое правило.
Ответы
Ответ 1
Итак, после большого раздражения, я понял проблему, вроде. Как оказалось, правило в моем первоначальном вопросе фактически делало именно то, что предполагалось. Так было сделано несколько других способов сделать то же самое, например
RewriteRule ^wp-content/uploads/.*$ - [L]
(Отметьте правило как последнее, если шаблон совпадает) или
RewriteRule ^wp-content/uploads/.*$ - [S=1]
(Пропустите следующее правило, если шаблон совпадает), а также отрицательное правило в вопросе, как уже упоминалось. Все эти правила работали очень хорошо и вернули управление Apache без перезаписи.
Проблема возникла после обработки этих правил. Вместо этого проблема заключалась в том, что я удалил стандартные шаблоны 404.shtml, 403.shtml и т.д., Которые предоставил мой хост. Если у вас нет каких-либо перезаписей .htaccess, это работает нормально; сервер будет готовить свою собственную страницу 404 по умолчанию, и все будет работать. (По крайней мере, это то, что я думал, но на самом деле это была двойная ошибка ". Кроме того, при попытке использовать ErrorDocument для обработки запроса была обнаружена ошибка 404 Not Found." )
Когда у вас есть .htaccess, с другой стороны, он выполняется второй раз для страницы 404. Если страница есть, она будет использоваться, но теперь запрос 404.shtml был пойман с помощью правила catch-all и переписан на index.php. По этой причине все другие предложения, которые я получил здесь или в другом месте, потерпели неудачу, потому что в итоге страница 404 была переписана index.php.
Итак, решение было просто восстановить шаблоны ошибок. Оглядываясь назад, было довольно глупо удалять их, но у меня этот менталитет "начать с нуля". Не хочу, чтобы что-то казалось ненужным. По крайней мере, сейчас я понимаю, что происходит, чего я хотел.
Наконец, комментарий к Сесилу: я никогда не хотел запрещать доступ ко всему, просто прекратите переписывать. Не то, чтобы это имело значение сейчас, но я просто хотел прояснить это.
Ответ 2
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} !^/wp-content/uploads/ [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Ответ 3
Если /wp-content/uploads/
действительно является префиксом запрошенного пути URI, ваше правило должно работать как ожидалось.
Но поскольку он, очевидно, не работает, попробуйте не сопоставлять префикс пути полного пути URI, а только оставшийся путь без контекстного префикса пути для каждого каталога, в случае файла .htaccess в корневой директории документа URI путь без ведущего /
:
RewriteCond $0 !^wp-content/uploads/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .+ /index.php [L]
Если это не работает, это, безусловно, поможет получить представление о процессе перезаписи mod_rewrites, используя функцию ведения журнала. Поэтому установите RewriteLogLevel
на уровень не менее 4
, сделайте свой запрос и взгляните на записи в файле журнала, указанные в RewriteLog
. Там вы можете увидеть, как mod_rewrite обрабатывает ваш запрос, а с помощью RewriteLogLevel
больше или равно 4 вы также увидите значения переменных типа %{REQUEST_URI}
.