Przekierowanie adresu url polega na poinformowaniu przeglądarek internetowych, że ma wyświetlić inną stronę niż wpisywana do przeglądarki. Wszystko dzieje się automatycznie i jest często wykorzystywane przy skracaniu adresów www lub gdy np, jakaś strona/podstrona przestała istnieć i chcemy, żeby użytkownik został przeniesiony pod inny adres.


Nadpisanie adresu URL można przeprowadzić za pomocą modułu mod_rewrite (Apache) oraz ISAPI_rewrite (Microsoft IIS Server).
Narzędzia sprawdzają się na przykład w sytuacji, kiedy chce się przekierować adresy niedostępne wyszukiwarkom, na adresy bardziej dla nich przyjazne. Narzędzia sprawdzą się również w sytuacji, kiedy na witrynie została zmodyfikowana struktura adresów URL, a treści zmieniły swoją lokalizację. Dzieje się tak, podczas zmiany systemu zarządzania treścią czy architektury serwisu.
Na serwerze Apache, działanie polega na zapisaniu specjalnych dyrektyw (zasady napisywania z ang. rewrite rules) w pliku .htaccess lub pliku konfiguracji serwera (np. httpd.conf lub sites_conf). Na serwerze IIS należy wykorzystać wtyczkę ISAPI (np. ISAPI_Rewrite) i umieścić instrukcję w pliku httpd.ini. na początku pliku .htaccess należy wpisać:
RewriteEngine on
RewriteBase /
Drugi wiersz pomija się w przypadku, kiedy dodaje się tę funkcję w pliku konfiguracyjnym z tego powodu, że instrukcja RewriteBase jest obsługiwana tylko w pliku ,htaccess. Rewritebase sprawia, że nie trzeba wstawiać symboli „^/” przy każdej regule, a wystarczy tylko symbol „^”.
Następnym krokiem jest przejście do implementacji reguł. Na przykład jeśli chcemy, aby adres: http://www.mojastrona.com/produkty/666 spowodował wczytanie strony dostępnej pod adresem http://www.mojastrona.com/try_me.php?id=666, bez zmiany adresu w pasku przeglądarki i bez modyfikacji kodu w pliku „try_me”. Modyfikacja nie zastąpi wszystkich dynamicznych adresów URL w odnośnikach na wszystkich stronach. Można to rozwiązać poprzez:
RewriteRule ^produkty/([0-9]+)/?$ try_me.php?id=$1 [L]
Powyższa instrukcja oznacza, że wszystkie żądania zawartości katalogu „produkty/” powinny zostać przeniesione do pliku „try_me.php”, gdzie podkatalogi folderu „produkty/” stają się parametrami skryptu PHP.
Znaczenie znaków:
„^” – oznacza początek adresu URL po nazwie domeny
„$” – oznacza koniec adresu,
[0-9] – cyfry,
„+” – możliwość wystąpienia całej serii cyfr,
/? – oznacza wystąpienie znaku „/” jeden raz lub możliwość jego pominięcia,
() – ich zawartość umieszcza się w pamięci,
$1 – parametr umożliwia uzyskanie dostępu do zachowanych pamięci, dla drugiej pary nawiasów byłoby to $2,
[L] – nakazuje serwerowi przerwanie operacji, jeśli dopasuje regułę do przypadku, w innym razie serwer porówna wszystkie zdefiniowane reguły,
Bardziej złożony przykład:
Adres URL ma zostać przepisany z formatu:
http://www.mojastrona.com/webapp/wcs/sklepy/serwlet/WyswietlProdukty?storeId=10001&catalogId=10001&langId=-1&categoryID=4&productID=666
na:
http://www.mojastrona.com/4/666.htm.
RewriteRule ^([^/]+)/([^/]+)\.htm$
webapp/wcs/sklepy/serwlet/WyswietlProdukty?storeId=10001&catalogId=10001&
langId=-1&categoryID=$1&productID=$2 [QSA,L]
[^/] – ten ciąg znaków oznacza dowolny znak poza ukośnikiem; wewnątrz nawiasów kwadratowych znak „^” jest rozumiany jako słowo „nie”.
[QSA] – oznacza, że nie chcemy, by oryginalny łańcuch zapytań został pominięty.
Najważniejsze znaki i reguły ich interpretacji w wyszukiwarce:
* – oznacza zero lub więcej instancji poprzedzającego ten symbol znaku.
+ – oznacza jeden lub więcej instancji poprzedzającego ten symbol znaku.
? – oznacza zero lub jedną instancję poprzedzającego ten symbol znaku.
^ – początek łańcucha znaków, jeśli jest wewnątrz kwadratowych nawiasów, to oznacza słowo „nie”, np. [^$] oznacza „nie dolar”.
$ – zakończenie łańcucha znaków.
. – znak wieloznaczności, oznacza dowolny symbol.
\ – przywraca następującemu po nim znakowi pierwotne znaczenie (np. znak zapytania ma oznaczać znak zapytania).
Najbardziej popularne pomyłki w użyciu znaków:
- Jeśli użyje się .* zamiast .+ – wyrażenie .* jest prawidłowe również dla 0 znaków.
- Używanie wyrażeń, które będą pasować do wielu instancji, zamiast zatrzymać się na jednej, na przykład: RewriteRule ^(.*)/?index\.html$ /$1/ [L,R=301] – taka reguła przekieruje ze strony http://www.mojastrona.com/blah/index.html na stronę http://www.mojastrona.com/blah//, a na pewno nie o to tutaj chodziło. Symbole „.*” przechwycą wszystkie znaki ukośnika, zanim wyrażenie /? Zacznie działać. Można to zapisać w inny sposób. Zamiast „.*” w porównaniu można użyć „[^” lub „.*?”. W miejsce „^(.*)?” można wstawić „^(.*?)/?”. Albo w miejsce „.*/.*” można wstawić „[^/]*/[^/}*”. Reguła będzie się prezentować w następujący sposób: RewriteRule ^(.*?)/?index\.html$ /$1/ [L,R=301].
- Pominięcie znaków ^ oraz $ myśląc, że początek i koniec wynika z kontekstu.
- Pominięcie znaków przywrócenia, w przypadku znaków specjalnych, które powinny zostać zinterpretowane w naturalny sposób, na przykład wpisanie „.,” zamiast „\.”, a chcemy by znak został zrozumiany jako kropka.
- W połączenie z RewriteRule używa się również RewriteCond. Jest to bardzo funkcjonalna dyrektywa. Za jej pomocą można przyrównać treści z łańcucha zapytań, nazwy domeny i innej dowolnej zawartości, która nie występuje pomiędzy nazwą domeny, a znakiem zapytania w adresie URL. RewriteRule oraz RewriteCond nie mają dostępu do zakotwiczonej części adresu URL., czyli tekstu po znaku „#”. Część ta funkcjonuje w przeglądarce, dlatego nie ma potrzeby wysyłania jej na serwer. Przykład użycia RewriteCond:
RewriteCond %{HTTP_HOST} !^www\.mojastrona\.com$ [NC]
RewriteRule ^(.*)$ http://www.mojastrona.com/$1 [L,R=301]
RewriteCond przyrównuje nazwę hosta jeszcze przed wykonaniem reguły RewriteRule. Wykrzyknik „!”na początku wyrażenia jest interpretowany przez serwer jako słowo „nie”.
Umieszczenie znaku zapytania „?” na końcu docelowego adresu pokazuje, że zapytanie nie musi zostać zachowane.
RewriteCond %{HTTP_HOST} !^www\.mojastrona\.com$ [NC]
RewriteRule ^(.*)$ http://www.mojastrona.com/$1? [L,R=301]
Jeśli chce się usunąć identyfikator sesji lub parametr (np. source=baner_rekl) z adresu URL, zachowując jednocześnie inne parametry w łańcuchu, to można zapisać to w następujący sposób:
Dla adresu statycznego
RewriteCond %{QUERY_STRING} ^source=[a-z0-9]*$
RewriteRule ^(.*)$ /$1? [L,R=301]
Dla adresu dynamicznego
RewriteCond %{QUERY_STRING} ^(.+)&source=[a-z0-9]+(&?.*)$
RewriteRule ^(.*)$ /$1?%1%2 [L,R=301]
Przed przekierowaniem użytkownika, należy w pierwszej kolejności wywołać skrypt, który zapisze dane użytkownika w plikach cookie. Dopiero wtedy można użyć przekierowania 301 do kanonicznego adresu URL:
RewriteCond %{QUERY_STRING} ^source=([a-z0-9]*)$
RewriteRule ^(.*)$ /cookiefirst.php?source=%1&dest=$1 [L]
Innym problemem jest niepoprawne katalogowanie stron w adresach URL z nagłówkiem HTTPS, gdzie dochodzi do usunięcia ukośnika z łańcucha. Najpierw zajmujemy się protokołem HTTPS:
RewriteCond %{HTTPS} on
RewriteRule ^katalog/(.*) http://www.mojastrona.com/katalog/$1 [L,R=301]
W przypadku posiadania odrębnego serwera bezpieczeństwa, nie trzeba stosować wiersza RewriteCond, wystarczy ukośnik zamykający w regule:
RewriteRule ^(.*[^/])$ /$1/ [L,R=301]
Po zakończeniu opracowywania mechanizmów nadpisywania adresów URL, należy wycofać dynamiczną wersję adresu. Należy zastąpić wszystkie instancje na stronie i przekierować na statyczny odpowiednik. W taki sposób linki nakierowane na starsze wersje adresu URL, przekierują wyszukiwarkę i użytkowników na nowy adres. Zostanie od zaindeksowany i zapisany, a starsza wersja zostanie usunięta z baz danych wyszukiwarek. Można to zrobić w następujący sposób:
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteRule ^try_me\.php$ /produkty/%1.html? [L,R=301]
Trzeba uważać, by nie doszło do niekończącej się rekurencyjnej pętli przekierowań. Można to obejść poprzez dodanie do docelowego adresu bezsensownego parametru i skasowanie go tuż przed przekierowaniem. Na przykład:
RewriteCond %{QUERY_STRING} id=([0-9]+)
RewriteCond %{QUERY_STRING} !cos=cos
RewriteRule ^try_me\.php$ /produkty/%1.html? [L,R=301]
RewriteRule ^products/([0-9]+)/?$ /try_me.php?id=$1&cos=cos [L]
Podsumowując:
Do przepisania wykorzystuje się polecenie RewriteRule. Składnia komendy prezentuje się następująco:
RewriteRule maska_przepisania docelowy_adres [opcje/flagi]
maska_przepisania – adres/wzorzec, który umieszczany jest w adresie URL. docelowy_adres – plik lub adres, który jest fizycznie wywoływany.
[opcje] – przykładowe flagi do wykorzystania wraz z RewriteRule:
- R – (redirect), przekierowanie, [R=301].
- L – (last) – reguła zostanie wykonana jako ostatnia.
- F – (forbidden) – użyj tej flagi, aby zablokować dostęp do wybranego adresu URL.
- S – (skip) – omija określoną ilość następnych reguł. Przykład: wartość “S=3” ominie trzy następne reguły.
- E – umożliwia dodanie zmiennej środowiskowej.
- QSA – flaga zachowująca querystring.