Войти

Показать полную графическую версию : mod_rewrite etc.


Страниц : [1] 2 3 4 5 6 7 8 9 10

vadimiron
06-06-2004, 14:41
Вот только недавно познакомился с этим замечательным модулем

Вот что я вынес из данного знакомства-с помощью mod_rewrite можно:
1) Самое распространённое использование-перезапись урлов, например есть урл index.php?forum=webmaster&topic=45
можно переписать в index.php/webmaster/45, что для некоторых поисковых машин намного более лучший вариант
2)запретить доступ к определённому файлу
RewriteRule ^file.ext$ - [F]
3)запретить доступ определённому браузеру, сборщику почты, доступ с определённого айпи или пришедшим с определённого сайта
RewriteCond %{HTTP_USER_AGENT} ^Browser_Name [OR]
RewriteCond % {REMOTE_HOST} ^www.badsite.com$ [OR]
RewriteCond % {REMOTE_ADDR} ^169.45.23.01$
RewriteRule ^.*$ - [F]

Это было самое распространённое применение данного модуля, но есть ещё много всяких интересных хитростей:
наприсер я недавно нашёл такое применение-при вызове страницы pic.html, нужно показывать картинку дня, поэтому можно переписать этот урл в pic-06-06.html c помощью серверных переменных TIME_MON и TIME_DAY
RewriteRule ^pic.html$ pic-%{TIME_MON}-%{TIME_DAY}.html

Или ещё кому нравится можно переписать файл index.php кому очень захочется :) в index.bmp

Если кто ещё знает интересные применения данного модуля, то постите тут

mar
07-06-2004, 14:20
русский первод доков (http://www.opennet.ru/docs/RUS/mod_rewrite/)
еще (http://www.egoroff.spb.ru/portfolio/apache/)
и т.д. см. * на opennet (http://www.opennet.ru/search.shtml?words=mod_rewrite&restrict=&exclude=index)
А *вот (http://www.opennet.ru/search.shtml?words=mod_rewrite&config=&restrict=forum&exclude=index) проблемы и достижения в форумах *(все по тому же сайту)

а если реально кто чего еще интересного делает, то я тоже с удовольствием послушаю :)


Исправлено: mar, 0:11 9-06-2004

Prisoner
08-06-2004, 01:30
mar, к тебе тоже нижайшая просьба оформлять ссылки тегами форума. Пусть и не длинные ссылки, но смотрятся как-то... хм... не эстетично :). Не говорю уж о длинющих.

mar
09-06-2004, 00:12
Prisoner извинямс :user:

vadimiron
09-06-2004, 02:38
Prisoner-это по настоящему всё от лени можно же просто взять и скопировать из адресной строки браузра :) Но мы будем исправлятся:)

mar
У меня тут возникла такая проблема: надо переписывать адреса такого типа www.site.com/lalala в www.site.com/file.php?var=lalala - это без проблем получается, но у меня в этой же директории есть ещё папки, которые должны вызыватся как обычные папки и адрес на них не должен переписыватся
Я думал, так может пройти:
RewriteCond %{REQUEST_URI} !-d
но почему то не проходит :(
приходится каждую папку по отдельности перечислять:
RewriteCond %{REQUEST_URI} !papka_name

А если создам новою важную папку и забуду RewriteCond  дописать, то ничего хорошего из этого не выйдет, нужен какой то общий вариант, чтобы все папки отсекал

mar
09-06-2004, 12:19
vadimiron
не знаю, я ведь им не пользуюсь, хотя знаю, что есть очень большие любители :)
Мне не нравятся длинные ссылки в скриптах (и с ними не всегда можно защет POST cладить.) Но аналогично длинная система каталогов мне нравится, пожалуй, еще меньше :(
На сайты же ходят не только поисковики, но и люди :)

А что касается твоего вопроса - там, намколько мне помнится можно:
- поиграть regexp-ами
- подставить обрабатывающий скрипт (ну, он может, например, проверять реальное дерево каталогов и запрещать его переписывать)
Но это все общие соображения. Своего опыта работы с модулем  у меня нет.

vadimiron
17-08-2004, 00:34
Делать мне было нечего и решил я по данной теме маленькую статью накатать :)
Надеюсь кому нибудь поможет.
Ссылки на официальный мануал (перевод на русский):
Мануал (http://www.egoroff.spb.ru/portfolio/apache/mod_rewrite.html)
Ну сначало, проверьте, установлен ли этот модуль у вас. Внимание: это спец модуль к апачу, с другими серверами он *не работает.
Все команды данного модуля пишуться в файл .htaccess, причём если уже что то в данном файле стоит, то можно смело писать со следущей строки.
Команды модуля состоят из определённых директив, вот они :
RewriteEngine
RewriteBase
RewriteCond
RewriteLock
RewriteLog
RewriteLogLevel
RewriteMap
RewriteOptions
RewriteRule
Скажу честно, что не всеми директивами я пока владею, но всё основное сейчас опишу.
Начинается вся красота с включения модуля
RewriteEngine on
Эта первая строчка, которая должна присутствовать, чтобы модуль заработал, причём если далее следует много различных директив, достаточно поставить RewriteEngine off, чтобы деактивировать действие всех команд, не надо при этом комментировать все строчки.
Вторая обязательная строчка, без которой механизм преобразований работать не будет:
Options +FollowSymlinks
Если ваш системный администратор запрещает Вам использование «Options +FollowSymlinks», Вы не сможете ограничить использование mod_rewrite для отдельных каталогов, вместо этого изменения будут действовать на весь сервер.
Следущей обязательной командой нужно определить базовый URL (область) работы модуля, этим занимается директива RewriteBase:
RewriteBase /
"/" эквивалентно http://yoursite.com, но можно конечно и другой базовый URL указывать(например, когда URL'ы НЕ прямо соответствуют физическим путям, но об этом подробнее в официальном мануале)
Следущая интересная директива это RewriteLog, как ни сложно догадаться, она служит для определения файла ведения логов работы модуля. Пример из мануала:
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
Раз уж говорим про ведение журнала, то ещё одна директива по этому поводу: RewriteLogLevel а, причём а равно от 0 до 9, где 0=журнализация не ведётся, 9=записываються почти все действия модуля.
Ну а теперь самое интересное: директива RewriteRule-она как раз занимается обработкой и перезаписью урлов (и не только этим).
На каждое правило пишется свой RewriteRule. Также очень важен порядок, надо следить, чтобы второй RewriteRule не испортил работу первого RewriteRule, то есть чтобы они не пересекались.
В общем виде выглядит это так:
RewriteRule шаблон действие
Шаблон-это "нормальный урл", который мы ищем для обработки. Шаблон основан на ПЕРЛ-совместимых регулярных выражениях. Действием же может быть "новый урл", то есть тот урл, который мы хотим получить в результате обработки, или какой нибудь флаг (будут ниже рассмотрены).
Также следует отметить, что в RewriteRule и RewriteCond(следует ниже) можно использовать переменные сервера (%{VARNAME}) (их полный список в официальном мануале).
Ну теперь перейдём к простому примеру:
RewriteRule ^file.ext$ - [F]
^ якорь начала строки
$ якорь конца строки
file.ext какой то любой файл
[F] флаг, обозначающий запрещение.
То есть вся строка обозначает, что при вызове данного файла будет выдана ошибка номер 403.
Следущий пример: перед нами стоит задача-вместо такого урла topic.cgi?forum=20&topic=1089, получать такой topic.cgi/20/1089
RewriteRule ^topic\.cgi/(\d{,2})/(\d{,5})$ topic.cgi?forum=$1&topic=$2
Сначало замечу: то, что в шаблоне пишеться в скобках, используется потом в качестве переменных в действии (в порядке возникновения скобок получаем $1, $2, $3 ....).
Теперь как действует предыдущий пример: есть например такой запрос topic.cgi/20/1089, данная строка сверяется с шаблоном и если строка совпадает с шаблоном, что и происходит в нашем случае, урл трансформируется в topic.cgi?forum=20&topic=1089 и далее идёт вызов именно этого урла.
20 в нашем случае = $1 ( то есть(\d{,2}) ), а 1089-$2 ( то есть(\d{,5}) ).
Ещё один пример: мы перенесли папку soccer из корня сайта в папку sport, и не хотим переписывать все ссылки (ну и ссылки в избранном юзеров мы не сможем поменять)
RewriteRule ^soccer/(.*)$ sport/soccer/$1
(.*) равно $1 и обозначает любые знаки в любом количестве, так как вряд ли вызывается просто папка, наверняка какой нибудь файл из даной папки со своими переменными и тд.

Следует отметить, что RewriteRule не так часто употребляется в одиночестве, чаще его действие ограничивается условием, когда может выполняться данный RewriteRule. Условие выполнено в виде отдельной директивы RewriteCond. Главное здесь, что условие должно быть прописано перед правилом. На одно правило может приходится несколько условий (все эти условия должны быть выполнеными, чтобы перейти к выполнению правила, но также условия можно связать словом "или"-для этого в конце каждого условия, кроме последнего, ставится флаг [OR]).
В общем виде условие выглядит так: RewriteCond СравниваемаяСтрока Условие
СравниваемаяСтрока в 99% выражается серверной переменной (но также может быть простым текстом с использованием например переменной($1, $2, $3...), созданной в правиле, к которому относится данное условие), условие же это шаблон, то есть регулярное выражение с некоторыми дополнениями. Данные дополнения выписываю просто из мануала:
'<Условие' (лексически меньше)
Условие считается простой строкой и *лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически меньше чем Условие.
'>Условие' (лексически больше)
Условие считается простой строкой и *лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически больше чем Условие.
'=Условие' (лексически равно)
Условие считается простой строкой и лексически сравнивается с СравниваемаяСтрока. Истинно если СравниваемаяСтрока лексически равно Условие, т.е. эти две строки полностью одинаковы (символ в символ). Если Условие имеет вид "" (два знака дюйма идущих подряд) это сравнивает СравниваемаяСтрока с пустой строкой.
'-d' (является ли каталогом)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является каталогом.
'-f' (является ли обычным файлом)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является обычным файлом.
'-s' (является ли обычным файлом с ненулевым размером)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является обычным файлом, размер которого больше нуля.
'-l' (является ли символической ссылкой)
СравниваемаяСтрока считается путем, проверяется существование этого пути и то что этот путь является символической ссылкой.
'-F' (проверка существования файла через подзапрос)
Проверяет через все списки контроля доступа сервера, существующие в настоящий момент, является ли СравниваемаяСтрока существующим файлом, доступным по этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с осторожностью *— это отрицательно сказывается на производительности сервера!
'-U' (проверка существования URL через подзапрос)
Проверяет через все списки контроля доступа сервера, существующие в настоящий момент, является ли СравниваемаяСтрока существующим URL, доступным по этому пути. Для этой проверки используется внутренний подзапрос, поэтому используйте эту опцию с осторожностью *— это отрицательно сказывается на производительности сервера!

Пример
RewriteCond %{REMOTE_ADDR} ^212.37.64.23$
RewriteRule ^.*$ - [F]
Если REMOTE_ADDR равен 212.37.64.23, то ставим запрет на любой запрос, исходящий с данного айпи

RewriteCond %{REMOTE_HOST} ^www.somesite.com$
RewriteRule ^.*$ page.html
Всех, пришедших по ссылкам, расположенным на сайте www.somesite.com, перенаправляем на страницу page.html

RewriteCond %{REQUEST_URI} !uri1
RewriteCond %{REQUEST_URI} !uri2
RewriteCond %{REQUEST_URI} !uri1
RewriteRule ^([a-zA-Z0-9_-]{3,40})$ user.php?user=$1
Если ури не равен uri1, uri2 или uri3, то переписываем данный ури ([a-zA-Z0-9_-]{3,40}-это я так данный ури выразил) как user.php?user=$1 (вместо $1 можно было бы написать %{REQUEST_URI}, по сути получается то же самое)

Вроде, если в кратце рассказывать-это всё.
Ещё пару интересных примеров, которые я нашёл на различных сайтах:
Пример 1
Цель – показать посетителям «фото дня». Посетитель, кликнувший по ссылке http://yoursite.com/pic.html увидит лучшую
фотографию или картинку дня, и так каждый день. Мы будем работать с серверными переменными:
TIME_MON
TIME_DAY
Поместим в файл .htaccess одну единственную строку:
RewriteRule ^pic.html$ pic-%{TIME_MON}-%{TIME_DAY}.html
Запрашиваемый URL будет перезаписан, например:
pic-08-28.html
pic-08-29.html
pic-08-30.html
и так далее.
Теперь, все что вы должны сделать – это единожды загрузить файлы с соответсвующими именами и
забыть о ежедневном обновлении ссылки. Переменные времени также могут использоваться для другой периодичности.

Пример 2
Проблема отсутствующего завершающего слэша
Описание:
Каждый вебмастер может спеть песню о проблеме отсутствующих завершающих слэшей при использовании URL ссылающихся на каталоги.
Если они отсутствуют, сервер выдает ошибку, потому что если вы пишете /~quux/foo вместо /~quux/foo/ сервер ищет файл foo.
И поскольку этот файл является каталогом, происходит ошибка. В действительности, в большинстве случаев это исправляется само, однако,
в некоторых случаях, нужно самим эмулировать этот механизм.
Например, после того, как вы сделали массу сложных редиректов URL на CGI скрипты и т.д.

Решение:
Решение этой тонкой проблемы — это позволить серверу добавлять завершающий слэш автоматически.

Чтобы сделать это правильно, мы должны использовать внешний редирект, для того чтобы браузер правильно запрашивал картинки и пр.
В случае если бы мы *сделали только внутренний редирект, это бы работало только для самой страницы каталога (страницы по-умолчанию),
однако были бы проблемы при наличии любых картинок на этой странице с относительными URL,
потому что браузер сделал бы запрос на вставку in-lined объекта. Например, запрос для image.gif на странице /~quux/foo/index.html
без внешнего редиректа выглядел бы как /~quux/image.gif!

Поэтому, для того чтобы сделать это трюк, мы пишем:

RewriteEngine *on
RewriteBase * */~quux/
RewriteRule * *^foo$ *foo/ *[R]

Сумашедший и ленивый может даже сделать следущее в *файле .htaccess находящемся в корне веб-пространства своего сайта.
Однако, следует отметить, что это создает некоторые накладные расходы.

RewriteEngine *on
RewriteBase * */~quux/
RewriteCond * *%{REQUEST_FILENAME} *-d
RewriteRule * *^(.+[^/])$ * * * * * $1/ *[R]


Пример 3
Поиск страниц больше чем в одном каталоге
Описание:
Иногда необходимо позволить веб-серверу искать страницы больше чем в одном каталоге. Здесь вам не помогут ни MultiViews ни *другие техники.

Решение:
Мы пишем явный набор правил который ищет файлы в каталогах.

RewriteEngine on

# * во-первых попытаемся найти это в указанном месте/...
# * ...и если нашли то заканчиваем поиск и сидим и радуемся:
RewriteCond * * * * /your/docroot/dir1/%{REQUEST_FILENAME} *-f
RewriteRule *^(.+) */your/docroot/dir1/$1 *[L]

# * во-вторых - попытаемся найти это в pub/...
# * ...и если нашли то заканчиваем поиск и сидим и радуемся:
RewriteCond * * * * /your/docroot/dir2/%{REQUEST_FILENAME} *-f
RewriteRule *^(.+) */your/docroot/dir2/$1 *[L]

# * иначе продолжаем для других директив Alias или ScriptAlias,
# * и т.д.
RewriteRule * ^(.+) *- *[PT]



Короче ещё много чего можно придумать :)

И наполедок ещё две директивы: RewriteMap и относящиеся к ней RewriteLock. Директива RewriteMap-ассоциативный массив преобразований, который может быть использован в правилах преобразований и использующий соответствующие функции для вставки/извлечения элементов, для поиска по ключу соответствующих значений. Источник этого поиска может иметь различный тип. Но я этим не умею пользоваться, подробности смотрим в мануале.

Исправлено: Prisoner, 3:43 29-08-2004

mar
19-10-2004, 23:27
а мне тут приспичило закрывать доступ скрипткидесам (ну достали, прямо скажем)
вот (http://www.mylib.kiev.ua/view.php?id=358) вариант - когда закрывается доступ списку ip и машин:
Решение:
Для Apache версий >= 1.3b6:

RewriteEngine on
RewriteMap    hosts-deny  txt:/path/to/hosts.deny
RewriteCond  ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND} !=NOT-FOUND [OR]
RewriteCond  ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND} !=NOT-FOUND
RewriteRule  ^/.*  -  [F]

Для Apache версий <= 1.3b6:

RewriteEngine on
RewriteMap    hosts-deny  txt:/path/to/hosts.deny
RewriteRule  ^/(.*)$ ${hosts-deny:%{REMOTE_HOST}|NOT-FOUND}/
RewriteRule  !^NOT-FOUND/.* - [F]
RewriteRule  ^NOT-FOUND/(.*)$ ${hosts-deny:%{REMOTE_ADDR}|NOT-FOUND}/
RewriteRule  !^NOT-FOUND/.* - [F]
RewriteRule  ^NOT-FOUND/(.*)$ /

##
##  hosts.deny
##
##  ВНИМАНИЕ! Это ассоциативный массив, а не список, даже если мы его относим к списку.
##            mod_rewrite берёт из него пары ключ/значение, поэтому, для каждой записи,
##            должно быть представлено по крайней мере фиктивное значение "-".
##

193.102.180.41 -
bsdti1.sdm.de  -
192.76.162.40  -

ну, а дальше пишем скрипт, который анализирует логи апача и всех эксперементаторов туда прописывает. По крону и без права замены штрафом ;)

Добавлено:

хм, печально, но факт - для броузеров вышеперечисленные мной запреты честно генерят отлупы, а вот от такой штуки не спасают:
telnet ххх.ххх.ххх.ххх 80
Trying ххх.ххх.ххх.ххх...
Connected to ххх.ххх.ххх.ххх.
Escape character is '^]'.
то есть пустили по http порту и ничем наш модуль не помог :(

CodeMaker
16-02-2005, 08:40
Вот блуждал по инертену и наткнулся вот на что, на сайте
http://www.apache.tut.ru/

кликая по ссылке в которой прописано http://far.h1.ru/serv/apache/#c2
попадаешь опять на этот адрес http://www.apache.tut.ru/ как это реализовано? По какой ссылке нажмешь в стусно строке остается все тожа и страницу грузится по другим ссылкам.


Вобмщем вопрос такой :))
как сделать чтобы в статусной сроке было прописано к примеру
http://www.apache.tut.ru/ но загружались страницы
http://far.h1.ru/serv/apache/#c2
http://far.h1.ru/serv/apache/#c3
http://far.h1.ru/serv/apache/#c3
в зависимости от того по какой из сылок перейти

Prisoner
17-02-2005, 10:20
Не совсем понятный вопрос, если честно. В описании имеет место быть банальный редирект. Поглядите окументацию и примеры приведенные выше. Это вам необходимо.

vadimiron
19-02-2005, 16:35
CodeMaker, Prisoner
Не, там просто фреймовая структура реализована
Материнский фрейм занимает всю страницу, но ничего не отображает, а весь контент находится в дочернем фрейме, который тоже занимает всю страницу, но ложиться сверху на материнский, то есть при нажатии на ссылки происходить загрузка в дочку, а по правилам браузера в адресной строки всегда стоит адрес матери, и так как в маму ничего не грузим, то и адрес не меняется

ABrun
16-07-2005, 14:53
Может кто знает... с помощью mod_rewrite надо очень решить такую задачку:

Есть сервер А на котором несуществующая ссылка типа http://serverA.com/top/

Нужно, чтобы открылся скрипт тор-листа, но на сервере B, где он и установлен. И при этом важно, чтобы URL в строке запроса оставался http://serverA.com/top/ даже если перехожу по относительным ссылкам этого скрипта.

То есть, если понятнее - надо показывать папку сайта В под своим доменом (сайт А). Типа это моя папка.... :)

vadimiron
16-07-2005, 16:13
Примерно так:
RewriteRule ^http://serverA.com/top/$ http://serverB.com/top/

Surround
25-07-2005, 21:57
:sorry:
извиняюсь, читал-читал, пытался, но так и не получилось, чтобы URL типа site.net/?action=view записывался как site.net/view или просто как site.net, чтобы все срезалось. Такое возможно?

ABrun
25-07-2005, 22:11
Наверно так должно получится-

RewriteRule ^\?action\=view(.*) http://www.site.net$1

Но я не уверен, уже были похожие проблемки -
?action=view содержит символы - ?=, советуют их экранировать \ попробуй,
может получится.

посмотри еще есть две классные статьи с примерами -
http://www.egoroff.spb.ru/

Surround
21-08-2005, 02:02
Вообще задача такая: чтобы запрос вида test.php?d=.. был виден в строке браузера как просто test.php или еще что-нить левое. чтобы скрыть передаваемые перменные. такое возможно?

Prisoner
22-08-2005, 14:58
Можно скрыть в других данных: test/fh483jfg89e83mjr9j4. Тут мусор слева и справа можно генерить случайным образом, но определенной длины, т.о. найти необходимое не составит труда - в примере некий параметр пусть будет равен 89. Иначе, имхо, только с финтами ушами более финтового порядка: кукисы, POST запросы, фреймы.

benya
13-09-2005, 11:12
Кстати, почему данный модуль не работает на Win32?

Prisoner
13-09-2005, 15:13
Отчего же... проверьте все еще раз, все корректно работает, впервые слышу о таком.

benya
13-09-2005, 20:42
Гм.... что нужно сделать что бы заработал модуль? По сути расскоментировать две строки в конфигурационном файле апача. Я все сделал - не работает.




© OSzone.net 2001-2012