Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Перенаправить запросы, только если файл не найден?

Автор вопроса: DivideByHeroОтветов: 5

Я надеюсь, что есть способ сделать это с помощью mod_rewrite и Apache, но, возможно, есть и другой способ.

На моем сайте я создал каталоги для обновленных версий сайта для клиентов. Если веб-корень /home/blah/www, каталог клиента будет /home/blah/www/clients/abc. Когда вы получаете доступ к каталогу клиента через веб-браузер, я хочу, чтобы он использовал любые запрошенные файлы в каталоге клиента, если они существуют. В противном случае я хочу, чтобы он использовал файл в корневом каталоге.

Например, допустим, клиенту не нужен собственный index.html. Поэтому какой-то код определит, что в /home/blah/www/clients/abc нет index.html, и вместо этого будет использовать тот, что в /home/blah/www. Имейте в виду, что я не хочу перенаправлять клиента в корневой каталог в любое время, я просто хочу использовать корневой веб-файл с таким именем, если в клиентском каталоге не указана его собственная копия. Веб-браузер по-прежнему должен указывать на /clients/abc независимо от того, существует ли файл там или в корне. Аналогичным образом, если есть запрос на news.html в клиентском каталоге и он действительно там существует, то просто отправьте этот файл вместо news.html корневого веб-узла. Опыт пользователя должен быть бесшовным.

Мне нужно, чтобы это работало для запросов на любое имя файла. Если мне нужно, например, добавить новую строку в .htaccess для каждого файла, который я, возможно, захочу перенаправить, это скорее сведет на нет цель, поскольку требуется слишком много обслуживания и велика вероятность ошибок, учитывая большое количество файлов.

В своих примерах укажите, находится ли ваш код в файле .htaccess в каталоге клиента или в корневом каталоге веб-сайта. Предпочтителен веб-корневой каталог.

apachemod-rewrite

Ответы

Ответ 1 · рейтинг 28 · Jeremy L

# If requested resource exists as a file or directory, skip next two rules
RewriteCond %{DOCUMENT_ROOT}/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule (.*) - [S=2]
#
# Requested resource does not exist, do rewrite if it exists in /archive
RewriteCond %{DOCUMENT_ROOT}/archive/$1 -f [OR]
RewriteCond %{DOCUMENT_ROOT}/archive/$1 -d
RewriteRule (.*) /archive/$1 [L]
#
# Else rewrite requests for non-existent resources to /index.php
RewriteRule (.*) /index.php?q=$1 [L]

From Переписать, если файлы не существуют

Ответ 2 · рейтинг 10 · Happy

Как насчет этого?

# If requested resource exists as a file or directory go to it
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*) - [L]

# Else rewrite requests for non-existent resources to /index.php
RewriteRule (.*) /index.php?q=$1 [L]

Ответ 3 · рейтинг 8 · DivideByHero

Кажется, у меня была по крайней мере одна проблема с каждым из приведенных выше примеров. %{DOCUMENT_ROOT}, похоже, в некоторых местах работает неправильно, а некоторые символы /, похоже, отсутствуют. Вот мое решение, которое находится в папке .htaccess в корневом каталоге.

Вместо того, чтобы использовать два правила (одно для случая, когда файл в client/ найден, и одно для не найденного), все, что мне нужно проверить, это то, что запрошенный файл (или каталог) НЕ существует. Потому что, если он существует, никаких изменений не требуется, он может просто использовать файл, предоставленный в каталоге клиента. Вот код, на котором я остановился:

RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}/clients/$1/$2 !-f
RewriteCond %{DOCUMENT_ROOT}/clients/$1/$2 !-d
RewriteRule ^clients/([^/]+)/(.*)$ $2 [L]

Спасибо за вашу помощь!

Ответ 4 · Gumbo

Попробуй это:

RewriteEngine on
RewriteRule ^clients/abc/ - [L]
RewriteCond %{DOCUMENT_ROOT}clients/abc/$0 -f
RewriteRule .* clients/abc/$0 [L]

Ответ 5 · jcrossley3

Я думаю, вы хотите что-то в этом роде:

RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}clients/$1/$2 -f
RewriteRule ^clients/([^/]+)/(.*)$ %{DOCUMENT_ROOT}clients/$1/$2 [L]
RewriteRule ^clients/([^/]+)/(.*)$ %{DOCUMENT_ROOT}$2 [L]

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы