RewriteCond в .htaccess с отрицательным условием регулярного выражения не работает? - PullRequest
17 голосов
/ 28 января 2011

Я пытаюсь помешать, в этом случае WordPress, переписать определенные URL-адреса. В этом случае я пытаюсь предотвратить обработку запроса в каталоге загрузки, а вместо этого оставить его на странице 404 сервера. Поэтому я предполагаю, что это так же просто, как добавить правило:

RewriteCond %{REQUEST_URI} !^/wp-content/uploads/

Это правило должно принимать значение false и приводить к сбою цепочки правил для этих запросов, что останавливает перезапись. Но нет ... Возможно, мне нужно сопоставить обложку с полной строкой в ​​моем выражении?

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 по умолчанию плюс мое правило.

Ответы [ 4 ]

10 голосов
/ 28 января 2011
<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>
7 голосов
/ 29 января 2011

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

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.

Итак, решение было просто восстановить шаблоны ошибок. Оглядываясь назад, было довольно глупо удалять их, но у меня есть этот менталитет «с нуля». Не хочу ничего, казалось бы, ненужного валяться. По крайней мере, теперь я понимаю, что происходит, чего я и хотел.

Наконец, комментарий к Сесилу: я никогда не хотел запрещать доступ к чему-либо, просто остановил переписывание. Не то чтобы сейчас это имело большое значение, но я просто хотел уточнить это.

3 голосов
/ 28 января 2011

Если /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_rewrite с помощью функции logging . Поэтому установите RewriteLogLevel на уровень не менее 4, сделайте запрос и посмотрите на записи в файле журнала, указанные в RewriteLog. Там вы можете увидеть, как mod_rewrite обрабатывает ваш запрос, и с RewriteLogLevel, большим или равным 4, вы также увидите значения переменных, таких как %{REQUEST_URI}.

0 голосов
/ 19 августа 2018

Я нашел много примеров, подобных этому, когда подход «WordPress First».Например, добавление:

ErrorDocument 404 /error-docs/404.html

в файл .htaccess позаботится о сообщении («Кроме того, ошибка 404 Not Found ...»).

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