Модуль mod_rewrite ч.3

У двох попередніх частинах ми познайомилися з основами «правил перезапису» URL і «умовами правил». Дозвольте запропонувати до розгляду два приклади, що ілюструють більш складні додатки.

Перший приклад має справу з динамічними сторінками, а другий показує можливості виклику «.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 ^.htaccess*$ - [F]

Однак ми ще не досягли справжньої перезапису URL адрес, в сенсі того, що один URL повинен перенаправляти відвідувача на інший.

Для нашої записи виду: 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'}» і т.д. Це забезпечить отримання всієї необхідної інформації. Ось вихідний текст для сценарію cgi, згаданого вище: #!/usr/bin/perl # If required, adjust line above to point to Perl 5. ################################# # (c) Copyright 2000 by fantomaster.com # # All rights reserved. # ################################# $stats_dir = "stats"; $log_file = "stats.log"; $remote_host = "$ENV{'REMOTE_HOST'}"; $remote_addr = "$ENV{'REMOTE_ADDR'}"; $user_agent = "$ENV{'HTTP_USER_AGENT'}"; $referer = "$ENV{'HTTP_REFERER'}"; $document_name = "$ENV{'QUERY_STRING'}"; open (FILE, "robots.txt"); @TEXT = ; close (FILE); &get_date; &log_hits ("$date $remote_host $remote_addr $user_agent $referer $document_name "); print "Content-type: text/plain "; print @TEXT; exit; sub get_date { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(); $mon++; $sec = sprintf ("%02d", $sec); $min = sprintf ("%02d", $min); $hour = sprintf ("%02d", $hour); $mday = sprintf ("%02d", $mday); $mon = sprintf ("%02d", $mon); $year = scalar localtime; $year =~ s/.*?(d{4})/$1/; $date="$year-$mon-$mday, $hour:$min:$sec"; } sub log_hits { open (HITS, ">>$stats_dir/$log_file"); print HITS @_; close (HITS); } #!/usr/bin/perl # If required, adjust line above to point to Perl 5. ################################# # (c) Copyright 2000 by fantomaster.com # # All rights reserved. # ################################# $stats_dir = "stats"; $log_file = "stats.log"; $remote_host = "$ENV{'REMOTE_HOST'}"; $remote_addr = "$ENV{'REMOTE_ADDR'}"; $user_agent = "$ENV{'HTTP_USER_AGENT'}"; $referer = "$ENV{'HTTP_REFERER'}"; $document_name = "$ENV{'QUERY_STRING'}"; open (FILE, "robots.txt"); @TEXT = ; close (FILE); &get_date; &log_hits ("$date $remote_host $remote_addr $user_agent $referer $document_name "); print "Content-type: text/plain "; print @TEXT; exit; sub get_date { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(); $mon++; $sec = sprintf ("%02d", $sec); $min = sprintf ("%02d", $min); $hour = sprintf ("%02d", $hour); $mday = sprintf ("%02d", $mday); $mon = sprintf ("%02d", $mon); $year = scalar localtime; $year =~ s/.*?(d{4})/$1/; $date="$year-$mon-$mday, $hour:$min:$sec"; } sub log_hits { open (HITS, ">>$stats_dir/$log_file"); print HITS @_; close (HITS); }

Завантажте файл з даними вмістом в кореневу або в DocumentRoot директорію сервера і встановіть права доступу до файлу (chmod) 755. Потім, створіть каталог «stats».

Якщо налаштування вашого сервера не дозволяють виконувати cgi-сценарії в головній директорії (DocumentRoot), то спробуйте наступний варіант: RewriteRule ^robots.txt$ /cgi-bin/text.cgi?%{REQUEST_URI}

Зверніть увагу, що в цьому випадку, буде необхідно змінити шляху в коді скрипта!

Нарешті, ось рішення задачки, даної в попередній частині цієї публікації: RewriteCond %{REMOTE_ADDR} ^212.37.64 RewriteRule ^.*$ - [F]

Якщо ми пишемо в регулярному виразі «^ 212.37.64» замість «^ 212.37.64.» (З крапкою в кінці), то чи дасть це той же самий ефект, і чи будуть виключені ті ж самі IP адреси?

Регулярний вираз ^ 212.37.64 задовольняє і може бути застосовано до наступних рядках:

212.37.64
212.37.640
212.37.641
212.37.64a
212.37.64abc
212.37.64.12
212.37.642.12

Отже, остання цифра «4» може супроводжуватися будь-символьним рядком. Однак, максимальним значенням IP є адреса 255.255.255.255 - який має на увазі, що наприклад 212.37.642.12 - неправильний (неприпустимий) IP. Єдиний допустимий IP у вищенаведеному списку - 212.37.64.12!

Далі буде...