Тема 13. Управление URL на уровне веб-сервера: использование mod_rewrite
Модуль mod_rewrite является программным модулем веб сервера Apache (обратите внимание, что он не будет выполняться под другими веб серверами!). Его первичная функция – манипуляция действий с URL. Модуль очень универсален и разносторонен, поэтому мы рассмотрим его работу на множестве реальных примеров.
Mod_rewrite является модулем, который предоставляет "основанный на правилах механизм динамического изменения запрашиваемых URL-ов", и его возможности действительно очень широки. Однако нужно быть очень осторожным и даже дотошным при работе с этим модулем – некоторые ошибки могут привести к логической петле и, следовательно, полной неработоспособности сайта.
Прежде, чем мы сможем приступить к работе, вы должны будете проверить, установлен ли модуль на вашем веб сервере или нет. Скорее всего – нет, а потому в конфигурационном файле Apache httpd.conf найдите и откомментируйте строку:
LoadModule rewrite_module modules/mod_rewrite.so
Затем найдите строку, определяющую значение переменной AllowOverride, и убедитесь, что там выставлено:
AllowOverride All
Если с нижеприведёнными примерами сервер работает без ошибок – mod_rewrite действительно установлен и работает корректно. Если нет, вы получите следующее сообщение при запросе любой web-страницы с вашего сервера: 'Внутренняя ошибка сервера'. Также, вы увидите такую запись в файле 'error.log':
'Invalid command 'RewriteEngine', perhaps mis-spelled or defined by a module not included in the server configuration'.
Для работы с mod_rewrite вы должны использовать файл '.htaccess', помещённый в "папку сайта", с которой вы будете работать. Первые две записи запустят сам модуль:
RewriteEngine on
Options +FollowSymlinks
Совет: запись "RewriteEngine off" отменит все последующие команды. Это очень полезная особенность: вместо необходимости комментировать все последующие строки – всё, что вы должны сделать, это установить "off".
Если ваш системный администратор запрещает вам использование "Options +FollowSymlinks", вы не сможете ограничить использование mod_rewrite для отдельных каталогов, вместо этого изменения будут действовать на весь сервер.
Следующая необходимая запись - это:
RewriteBase /
'/' является корневым (основным) URL. Если у Вас какой-то другой URL, вы можете указать это в данной директиве, однако '/' - обычно эквивалентно адресу 'http://домен.ру'.
Предположим, что вы хотите защитить от несанкционированного доступа ваш файл .htaccess. На некоторых серверах вы можете легко читать этот файл просто вводя URL следующего формата в поле адреса вашего браузера: http://www.domain.com/.htaccess – серьёзное упущение защиты, так как содержание вашего .htaccess может показать важную информацию об установках и настройках вашего сайта человеку, знающему как эти знания применить против вас.
Чтобы блокировать этот доступ, запишем следующее:
RewriteRule ^.htaccess$ - [F]
это правило переводится так: если кто-то пробует обращаться к файлу .htaccess, система должна сгенерировать код ошибки 'HTTP response of 403' или '403 Forbidden - You don't have permission to access /.htaccess on this server'.
Конструкция ^.htaccess$ в этом регулярном выражении означает:
· ^ - якорь начала строки
· $ - якорь конца строки
· . - в регулярных выражениях точка '.' обозначает мета-символ и должна быть защищена обратным слэшем (backslash), если вы все-таки хотите использовать именно фактическую точку (см. подробнее лекцию 11 – про регулярные выражения).
Имя файла должно быть расположено точно между начальным и конечным якорем. Это будет гарантировать то, что только это определенное имя файла и никакое другое, сгенерирует код ошибки.
[F] - специальный 'запрещающий' флажок (forbidden).
В этом примере, файл ".htaccess" теперь будет состоять из таких строк:
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^.htaccess$ - [F]
Мы можем ограничивать "правило" при помощи различных "условий правила". "Правило" будет выполнено только в том случае, если перед ним будет встречен ряд условий.
Синтаксис: условие должно предшествовать правилу!
Возьмем еще один пример (запись в файле .htaccess):
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon
RewriteRule ^.*$ - [F]
Назначение первых трёх записей было подробно разобрано ранее. Их функция - включение 'движка перезаписи', то есть самого модуля.
Последние две строки запрещают доступ поисковому роботу под кодовым названием 'EmailSiphon' (имеется ввиду имя юзер-агента). Данный робот является сборщиком почтовых адресов с различных веб страниц.
Строка:
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon
состоит из трёх частей:
Директива (указание): RewriteCond
Проверочная строка: %{HTTP_USER_AGENT}
Образец условия: ^EmailSiphon
Проверочная строка - переменная сервера, которая может быть записана в общей форме:
% {ИМЯ_ПЕРЕМЕННОЙ}
Образец условия - регулярное выражение. Для более полного понимания темы стоит рассмотреть регулярные выражения как класс.
Если говорить о связи регулярных выражений и модуля mod_rewrite, то они используются в директивах RewriteRule и RewriteCond.
'^' обозначает начало строки. Из этого следует, что UserAgent должен начинаться со строки 'EmailSiphon' и ни с чего другого ('NewEmailSiphon', например, не работал бы). Но, поскольку данное регулярное выражение не содержит символ "$" (якорь конца строки), UserAgent мог бы быть, например, 'EmailSiphon2'.
Последняя строка нашего примера:
RewriteRule ^.*$ - [F]
определяет, что именно нужно делать, когда робот запросит доступ. Регулярное выражение '^.*$' означает: 'Доступ ко всем файлам запрещен'. Точка '.' в регулярном выражении - мета символ (подстановочный знак), означающий любой случайный символ. '*' означает то, что строка может встречаться неограниченное количество раз. В этом случае, независимо от имени запрошенного файла, будет выдана ошибка.
'EmailSiphon', конечно, не единственный почтовый сборщик. Другой известный член этого семейства - 'ExtractorPro'. Допустим мы хотим запретить доступ и этому роботу. В таком случае нам необходимо еще одно условие.
Теперь файл .htaccess будет выглядеть так:
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteCond %{HTTP_USER_AGENT} ^EmailSiphon [OR]
RewriteCond %{HTTP_USER_AGENT} ^ExtractorPro
RewriteRule ^.*$ - [F]
Третий аргумент [OR] (в первой строке RewriteCond) называется 'флагом'. Существуют два возможных флага:
· NC - не учитывать регистр букв.
· OR - означает 'или следующее условие'.
Флажок NC позволяет игнорировать регистр букв в искомом образце.
RewriteCond %{HTTP_USER_AGENT} ^emailsiphon [NC]
Эта строка определяет, что и "emailsiphon" и "EmailSiphon" будут признаны как идентичные выражения. Вы можете использовать сразу несколько флажков, разделяя их запятыми.
RewriteCond % {HTTP_USER_AGENT} ^EmailSiphon [NC, OR]
RewriteCond % {HTTP_USER_AGENT} ^ExtractorPro
Нет никаких ограничений по числу условий. Таким образом, вы можете блокировать 10, 100, 1000 или более известных почтовых сборщиков. Определение этих 1000 условий – просто вопрос загрузки сервера и прозрачности файла '.htaccess'.
В вышеупомянутом примере используется глобальная переменная 'HTTP_USER_AGENT'. Существуют также другие переменные:
· REMOTE_HOST
· REMOTE_ADDR
Например, если вы хотите заблокировать паука пришедшего с www.site.ru, вы можете использовать глобальную переменную 'REMOTE_HOST' таким образом:
RewriteCond % {REMOTE_HOST} ^www.site.ru$
RewriteRule ^.*$ - [F]
Если вы хотите заблокировать определенный IP адрес, условие будет выглядеть так:
RewriteCond % {REMOTE_ADDR} ^212.37.64.10$
RewriteRule ^.*$ - [F]
В регулярном выражении по проверке точного и полного IP адреса нужно использовать начальные и конечные якоря.
Также можно исключить целый диапазон:
RewriteCond %{REMOTE_ADDR} ^212.37.64.
RewriteRule ^.*$ - [F]
Этот пример показывает, как можно заблокировать диапазон IP адресов с 212.37.64.0 по 212.37.64.255.
Теперь мы рассмотрим два примера, иллюстрирующих более сложные случаи использования mod_rewrite.
Первый пример имеет дело с динамическими страницами, а второй показывает возможности вызова ".txt" файлов и произведение различных действий над ними.
Предположим, что у нас есть виртуальный магазин по продаже каких-то товаров. Клиенты обращаются к описаниям товаров через скрипт:
http://www.yoursite.com/cgi-bin/shop.cgi?product1
http://www.yoursite.com/cgi-bin/shop.cgi?product2
http://www.yoursite.com/cgi-bin/shop.cgi?product3
Эти адреса представлены как ссылки на большинстве страниц сайта. А теперь допустим, что вы решили добавить сайт для индексации в поисковые системы. Тут вас поджидает небольшая неприятность – не все поисковики принимают, понимают и индексируют URL, в которых содержится символ "?".
Более естественным и приемлемым для поисковика является URL вида:
http://www.yoursite.com/cgi-bin/shop.cgi/product1
В данном случае символ "?" заменяется на "/". Ещё более комфортабельный URL с точки зрения поисковика будет иметь вид:
http://www.yoursite.com/shop/product1
Для поисковика, "shop" теперь как-бы является директорией, содержащей товары product1, product2 и т.д. Если пользователь, со страницы результатов запроса в поисковике проследует по такой ссылке, то эта ссылка должна будет трансформироваться в ссылку: shop.cgi?product1.
Чтобы добиться такого эффекта можно использовать mod_rewrite, используя следующую конструкцию в файле .htaccess:
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^(.*)shop/(.*)$ $1cgi-bin/shop.cgi?$2
Переменные $1 и $2 составляют так называемые "backreferences". Они связаны с текстовыми группами. Вызываемый URL разбивается на части. Все, что находится перед 'shop', плюс все что находится после 'shop/' определяется и хранится в этих двух переменных: $1 и $2.
Для нашей записи вида:
RewriteRule ^(.*)shop/(.*)$ $1cgi-bin/shop.cgi?$2
применяется общий синтаксис:
RewriteRule текущийURL перезаписываемыйURL
Как видите, эта директива выполняет действительную 'перезапись' URL адреса. В дополнение к записям в файл .htaccess, нужно еще заменить все ссылки на сайте, которые имеют формат 'cgi-bin/shop.cgi?product', на ссылки вида: 'shop/product'. Теперь, когда поисковик найдет страницу с подобными ссылками, он проиндексирует сайт без всяких видимых проблем. Таким образом вы можете превратить чисто динамический сайт в сайт, выглядящий статическим, что явно принесет пользу в вопросе индексирования различными посковыми машинами. Обратите внимание на вид URL адресов на данном сайте. Вдобавок ко всему, они имеют еще и легкочитамую для человека структуру - ЧПУ (человекопонятный УРЛ). В нашем втором примере мы обсудим, как переадресовать запросы '.txt' файлов к сценарию программы.
Многие хостинг провайдеры, работающие с Apache предоставляют лог-файлы в общем формате. Это означает то, что они не будут соджержать поля с ссылающимися страницами и юзер-агентами.
Однако, относительно запросов к файлу 'robots.txt', предпочтительно иметь доступ ко всем этим данным, чтобы иметь больше информации о посещении поисковиков, чем просто знать их IP адреса. Для того, чтобы оганизовать это, в '.htaccess' должны быть следующие записи:
RewriteEngine on
Options +FollowSymlinks
RewriteBase /
RewriteRule ^robots.txt$ /text.cgi?%{REQUEST_URI}
Теперь при запросе файла 'robots.txt' наш RewriteRule переадресует посетителя (робота) к обрабатывающему запросы скрипту text.cgi. Кроме того, переменная передается скрипту, которая будет обработана в соответствии с вашими нуждами. 'REQUEST_URI' определяет имя запрашиваемого файла. В данном примере это - 'robots.txt'. Скрипт прочтет содержание 'robots.txt' и отправит его web-браузеру или роботу поискового сервера. Таким образом, мы можем считать хиты посетителей и вести свои лог-файлы.
С этой целью, скрипт будет использовать переменные окружения '$ENV {'HTTP_USER_AGENT'}' и т.д. Это обеспечит получение всей требуемой информации.
Теперь мы рассмотрим директивы, которые не поддаются определению на уровне директорий. Это означает то, что вы должны иметь доступ к файлу конфигурации веб сервера Apache (httpd.conf).
Если вы хотите вести логи всех операций, выполненных с помощью mod_rewrite, можно активировать это с помощью следующей записи:
RewriteLog /usr/local/apache/logs/mod_rewrite_log
RewriteLogLevel 1
Все манипуляции, произведенные mod_rewrite будут записываться в этот файл. Имя лог файла может быть любым. Вы можете указать абсолютный или относительный (относительно ServerRoot) путь к файлу.
Если вы хотите вести разные лог файлы для различных виртуальных хостов, то нужно ввести изменения в 'Раздел 3: Виртуальные сервера', например так:
ServerAdmin webmaster@yourdomain.com
DocumentRoot /usr/www/htdocs/yourdomain
ServerName yourdomain.com
RewriteLog /usr/apache/logs/yourdomain_mod_rewrite_log
RewriteLogLevel 1
RewriteLogLevel может быть определен в пределах диапазона от 1 до 8. Обычно достаточно первого уровня. Более высокие уровни используются для деббагинга.
Другая директива, которая является очень удобной в целях клоакинга - это так называемая карта перезаписи. Это - файлы, содержащие пары ключ/значение, обычно в формате текстового файла:
cde2c920.infoseek.com spider
205.226.201.32 spider
cde2c923.infoseek.com spider
205.226.201.35 spider
cde2c981.infoseek.com spider
205.226.201.129 spider
cde2cb23.infoseek.com spider
205.226.203.35 spider
Ключи, как вы видите, имена хостов или IP адреса. В этом простеньком примере значение всегда одно - 'spider'. Естественно, в реальном файле значения будут другие. Эта директива может быть записана в второй ('Конфигурация основного сервера') или третий ('Виртуальные сервера') раздел файла httpd.conf:
RewriteMap botBase txt:/www/yourdomain/spiderspy.txt
'Карта перезаписи' возымеет эффект на весь сервер.
Также, в файл .htaccess записывается:
RewriteCond ${botBase:%{REMOTE_HOST}} =spider [OR]
RewriteCond ${botBase:%{REMOTE_ADDR}} =spider
RewriteRule ^(.*).htm$ $1.htm [L]
RewriteRule ^.*.htm$ index.html [L]
Данные условия будут производить системную проверку: произведен ли запрос поисковиком. С этой целью производится поиск по файлу spiderspy.txt. Если ключ найден, будет возвращено значение 'spider', а 'условие' будет являться истинным.
Затем выполняется первый RewriteRule. Это означает то, что запрашиваемая '.htm' страница будет отдана поисковику. Переменная $1 равна части в круглых скобках '^(. *).htm$', то есть имя файла останется тем же самым.
Если же URL вызван обычным посетителем, то применяется второе 'правило': пользователь будет перенаправлен на страницу 'index.html'.
Поскольку '.htm' страницы будут читаться только 'пауками', они могут быть оптимизированы соответственно для поисковых серверов. Вы можете также использовать файл в формате 'dbm' вместо обычного текстового файла. Бинарный формат данных позволяет ускорить поиск, который является особенно важным, если вы работаете с очень большими списками поисковиков. Пример, данный выше, предлагает простые функциональные возможности клоакинга. Все обычные посетители будут всегда переадресовываться к странице 'index.html' и не будет вестись никаких логов файлов вне логов mod_rewrite.
Можно заменить несколько строчек кода php (perl и т.д.) в ваших приложениях, используя всего одну-две строки mod_rewrite. Последний пример проиллюстрирует это более подробно.
Цель - показать посетителям 'фото дня'. Посетитель, кликнувший по ссылке 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
и так далее.
Теперь, всё что вы должны сделать - это единожды загрузить файлы с соответсвующими именами и забыть о ежедневном обновлении ссылки. Переменные времени также могут использоваться для другой периодичности.
Не нашли, что искали? Воспользуйтесь поиском по сайту:
©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|