Как указать mod_rewrite исключения, к которым не следует применять правило?

Мне нужно создать виртуальные корневые директории для пользователей.

Ну, то есть, переписывать все запросы вида:


example.com<user_name>


на


example.com/user?name=<user_name>


и такой шаблон я таки сообразил как написать:


RewriteRule ^/([A-Za-z0-9_-]+)/?$ /user?name=$1 [PT,L]


но как сделать так, чтобы mod_rewrite не переписывал реально существующие в корне директории?

например /css, /js, /img, да там еще куча скриптов помимо /user имеется


Указывать их всех в шаблоне регулярного выражения, как исключения(что-то в духе: [^css|^js|^img… ]), я не думаю, что правильно, потому что исключений там будет больше дюжины…

UPD: В общем в моём случае, похоже, есть своя специфика…

Apache у меня используется в связке с Tomcat, через mod_jk


mod_jk настроен вот так:


JkMount / ajp13
JkMount /* ajp13
JkUnMount /*.html ajp13
JkUnMount /*.ico ajp13
JkUnMount /css/* ajp13
JkUnMount /img/* ajp13
JkUnMount /js/* ajp13


Поэтому статические файлы которые отдает сам апач(.html, .ico, .css etc) — их можно исключить способом, который уже предложили в первом комменте:


RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d


но запросы к сервлетам mod_rewrite по-прежнему будет переписывать.

Апач не знает, существуют ли они или нет, он их просто отдает на откуп tomcat'у

Поэтому на ряду с правильным поведением:


example.com<user_name> --> example.com/user?name=<user_name>


будет присутствовать и неправильное:


example.com/login --> example.com/user?name=login


(login — это servlet)


Как все же можно решить эту проблему?


UPD2: В общем решение оказалось простым:


RewriteCond %{REQUEST_URI} !=/login
RewriteCond %{REQUEST_URI} !=/user
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/([A-Za-z0-9_-]+)/?$ /user?name=$1 [PT,L]
  • Вопрос задан
  • 9944 просмотра
Пригласить эксперта
Ответы на вопрос 3
@ADOLF88HITLER
А зачем? Вы же не будете напрямую обращаться к папкам css, js, img. Скорее всего вы будете обращаться к файлам, которые лежат в них. Просто добавьте правило:
RewriteCond %{REQUEST_FILENAME} !-f
В таком случае, если будет прямое обращение к файлу, будь то css или js, ваш RewriteRule будет проигнорирован.
Ответ написан
@max_rip
Решение может и простое, но чуток не правильное. Допустим вы добавили новый сервлет, вы будете опять дописывать правила?
сделайте что-то вроде
RewriteCond %{REQUEST_URI} !=/app/*
Используйте /app/ во всем сервлетах и будет вам глобально счастье.
Ответ написан
KhanTengri
@KhanTengri Автор вопроса
Просто задачи, которые мне предстоит решать требуют того, чтобы сервлет-контейнер был как можно ближе к корню / притянут. Изначально все так и было, как вы предлагаете. Сервлет-контейнер обрабатывал всё в контексте /app/ В таком случае даже конструкцию RewriteCond с REQUEST_URI, которую вы предлагаете, писать не нужно. Достаточно только:

RewriteRule ^/([A-Za-z0-9_-]+)$ /app/user?name=$1 [PT,L]

И все запросы виртуальных директорий просто не будут касаться той, которую обрабатывает сервлет-контейнер. Однако в таком случае страница index в корне не может быть динамической… Она будет либо html(http://example.com/index.html) либо ее тоже rewrite'ом надо будет маппить на jsp или servlet в директории /app/, что неправильно.
В моем же примере index-страница может быть динамической(http://example.com/index.jsp) без rewrite'ов

Относительно того, что каждый сервлет придется прописывать в ручную — их не так много и они не так часто меняются/добавляются.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы