Как заставить mod_rewrite пропускать реальные файлы - PullRequest
1 голос
/ 18 марта 2012

У меня есть приложение, которое маршрутизирует все запросы через index.php.

Вот мои настройки:

  1. Я получаю доступ к приложению в http://www.example.com/sample/
  2. Вкл.файловая система, приложение находится в /home/chris/www/sample/
  3. Доступный через Интернет каталог приложения находится по адресу /home/chris/www/sample/app/web.
  4. DocumentRoot имеет значение /home/chris/www

/home/chris/www/sample/.htaccess настроен следующим образом:

RewriteEngine on

RewriteCond   %{REQUEST_URI}    ^/sample/(.+)$
RewriteCond   %{DOCUMENT_ROOT}/sample/app/web/%1  -f
RewriteRule   ^/sample/(.*)$    %{DOCUMENT_ROOT}/sample/app/web/%1 [L]

RewriteRule   ^(.+)$            index.php?ws_page=$1 [L,NC,QSA]

Я перепробовал несколько конфигураций, но не понял, почему я продолжаю получать 404 при вызовах «реальных» файлов.

Образец 404:

`http://www.example.com/sample/_css/960/reset.css`

(который я хочу переписать в /home/chris/www/sample/app/web/_css/960/reset.css)

РЕДАКТИРОВАТЬ

У меня уже естьпробовал

RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !-l

и они не работали, потому что префикс% {REQUEST_URI} не совпадает с префиксом файловой системы этих файлов.

РЕДАКТИРОВАТЬ 2

Чтобы уточнить, я хочу, чтобы запросы вида

`http://www.example.com/sample/foo/bar`

были переписаны в объект файловой системы /home/chris/www/sample/app/web/foo/bar, но только , если этот объект файловой системы существует.

Ответы [ 4 ]

1 голос
/ 19 марта 2012

Одна из самых больших проблем при чтении документации по mod_rewrite, касающаяся различий в поведении системы (это основные конфигурации и конфигурации vhost, которые apache читает при запуске, и эти процессы директив в контексте каждого каталога. См. подраздел Перезапись на каталог документации RewriteRule для получения дополнительной информации.

При использовании механизма перезаписи в .htaccess файлах префикс для каждого каталога (который всегда одинаков для определенного каталога) автоматически удаляется для сопоставления с шаблоном RewriteRule и автоматически добавляется после любого относительного ( не начинается с косой черты или имени протокола) подстановка встречает конец набора правил. См. Директиву RewriteBase для получения дополнительной информации о том, какой префикс будет добавлен обратно к относительным подстановкам.

и позже

Удаленный префикс всегда заканчивается косой чертой, это означает, что сопоставление происходит со строкой, которая никогда не имеет ведущей косой черты. Следовательно, шаблон с ^/ никогда не совпадает в контексте каталога. То, что вы сделали, это чтобы обойти это.

Кстати, именно поэтому всегда безопаснее указывать RewriteBase, так как без этого двигатель ошибается.

Кстати, эта вторая кавычка может быть неправильной, поскольку добавление префикса происходит во время выполнения набора правил, и если у вас есть успешное правило, относящееся к другой относительной ветви (то есть цель начинается с /), но без установленного флага [L], двигатель переходит к любым последующим правилам с установленным начальным /. Самое запутанное, поэтому мой общий совет никогда не опирается на провальные правила. Всегда вызывайте немедленное внутреннее или внешнее перенаправление при успешной замене в контексте для каждого каталога , так как механизм имеет это и несколько других ошибок в этой сквозной обработке.

1 голос
/ 18 марта 2012

У вас есть такой код:

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

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+sample/(.+)\s [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond /home/chris/www/sample/app/web/%1 -f [NC]
RewriteRule ^ /sample/app/web/%1 [L]

# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid symlink
RewriteCond %{REQUEST_FILENAME} !-l
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
0 голосов
/ 18 марта 2012

Безумные бонусные баллы тому, кто мне может объяснить, почему мой якорь EOS ($) был виноват в том, что RewriteRule не работает.

Я завелся с этим:

RewriteEngine on

RewriteCond   %{REQUEST_URI}    ^/sample/(.+)
RewriteCond   %{DOCUMENT_ROOT}/sample/app/web/%1  -f
RewriteRule   ^(.*)$            app/web/$1 [L,NC,QSA]

RewriteCond   %{REQUEST_URI}    !(^/sample/app/web)
RewriteRule   ^(.+)$            index.php?ws_page=$1 [L,NC,QSA]

Большое спасибо всем, кто помог мне диагностировать эту странность.

0 голосов
/ 18 марта 2012
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

Эти два правила будут пропускать файлы (-f) и каталоги (-d), которые действительно существуют.

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