.htaccess jest zazwyczaj domyślnie włączony, jeśli jednak administrator z jakiejś przyczyny w pliku konfiguracyjnym Apache’a zawarł opcję
AllowOverride None
to .htaccess nie zadziała. Dowcipni administratorzy mogą zrobić nam niespodziankę i w ustawieniach Apache’a zadeklarować inną niż domyślną nazwę .htaccess.
Umożliwia im to dyrektywa
AccessFileName .ustawienia
W takim przypadku zamiast .htaccess będziemy edytować plik .ustawienia, ponieważ to właśnie on odpowiadać będzie za konfigurację serwera. Na szczęście ma to miejsce bardzo rzadko.
Zazwyczaj plik .htaccess umieszczany jest w głównym katalogu, jednak można stworzyć go w każdym innym istniejącym. Zapisy zawarte w tym pliku funkcjonują dla danego katalogu oraz wszystkich podkatalogów w nim się znajdujących.
Co można osiągnąć za pomocą tego pliku?
Okaże się przydatny przy wszelkiego rodzaju przekierowaniach, tworzeniu komunikatów błędów i zmiany sposobu dostępu do naszej strony.
Przy każdorazowym odświeżeniu plik ten jest ponownie wczytywany, w związku z tym każda zmiana jest od razu widoczna.
Kiedy mamy już pewność, że istnieje możliwość zmiany ustawień za pomocą pliku, należy go stworzyć (chyba że istnieje) i zabrać się do edycji.
Zbiór .htaccess powinien mieć uprawnienia 644 (nadane przez polecenie chmod). Pozwoli to na dostęp do pliku przez serwer, ale uniemożliwi jego
zmianę z poziomu przeglądarki:
Chmod 644 .htaccess
Zanim przystąpimy do pierwszych zapisów w pliku, warto wspomnieć, że komentarze w pliku .htaccess wstawia się poprzedzając je znakiem #
#komentarz #kolejna linia komentowana
Po każdej linii zapisu musi także nastąpić enter.
Pisanie jednym ciągiem bez załamywania wierszy może sprawić, że wpisy nie będą funkcjonować.
Tak samo ostatnia linia w pliku .htaccess powinna być linią pustą.
Na początek warto zacząć od określenia domyślnego pliku strony WWW. W tym celu wykorzystamy dyrektywę {stala}DirectoryIndex{/stala}.
Można podać kilka nazw plików, trzeba jednak pamiętać o rozdzieleniu ich spacjami. Kolejność ma znaczenie – jeśli pierwszy nie zostanie
znaleziony, automatycznie zostanie wczytany drugi.
DirectoryIndex index.html index.php awaria.html
Powyższa instrukcja pokazuje kolejność wczytywania plików. Jeżeli zostanie odnaleziony plik index.html, to właśnie on będzie traktowany jako domyślny, a w przypadku jego braku, domyślnym będzie index.php itd. Korzystanie z tego typu dyrektywy bywa przydatne, jeśli główny plik strony ma inną nazwę niż index.php (wtedy zapis może wyglądać następująco):
DirectoryIndex start.html
A także, gdy planujemy zmiany na naszej stronie WWW. Wtedy bez zbędnej przebudowy możemy stworzyć stronę awaryjną, którą ustanawiamy jako domyślną:
DirectoryIndex awaria.html
Po skończeniu wprowadzania zmian można bez problemu powrócić do wcześniejszych ustawień.
Zmiana powiązań typów plików MimeType to rozszerzenia, które zwracane są przeglądarce po znalezieniu na serwerze danego typu pliku. Dany typ pliku powoduje konkretną reakcję ze strony przeglądarki. Zazwyczaj jest to otwarcie programu obsługującego plik o tym rozszerzeniu.
Większość rozszerzeń jest zdefiniowana w domyślnej konfiguracji serwera, jednak czasem może się zdarzyć, że będziemy chcieć dodać lub
zmienić daną definicję np.:
AddType text/html .txt #pliki z rozszerzeniem .txt będą odczytywane jako pliki .html
Taki zapis sprawia, że wszystkie pliki .txt będą rozpoznawane jako zwykle pliki .html.
Aby wymusić otwieranie plików skompresowanych w odpowiednich aplikacjach, wystarczy skorzystać z odpowiedniej definicji.
Często w przeglądarkach ten typ plików jest odczytywany w formie niezrozumiałego tekstu.
AddType application/zip .zip AddType application/x-gzip .gz AddType application/x-gtar .gtar AddType application/x-rar-compressed .rar AddType application/octet-stream .dmg AddType application/x-7z-compressed .7z
Sposób przypisania większości znanych formatów do aplikacji zawarto w listingu 1.
#css, html, xml, asp, flash i inne AddType text/css .css AddType application/xhtml+xml .xhtml AddType text/html .shtml AddType text/xml .xml AddType text/html .asp Addtype application/x-httpd-php .php AddType application/x-shockwave-flash .swf AddType application/x-director .dir .dcr .dxr .fgd AddType application/x-authorware-map .aam AddType application/x-authorware-seg .aas AddType application/x-authorware-bin .aab AddType image/x-freehand .fh4 .fh5 .fh7 .fhc .fh AddType application/x-java-applet .class # dokumenty AddType application/pdf .pdf AddType application/msword .doc #multimedia AddType audio/mpeg .mp3 AddType video/x-msvideo .avi AddType audio/x-wav .wav AddType video/quicktime .mov .qt AddType video/x-ms-asf .asf .asx AddType audio/x-ms-wma .wma AddType audio/x-ms-wax .wax AddType video/x-ms-wmv .wmv AddType video/x-ms-wvx .wvx AddType video/x-ms-wm .wm AddType video/x-ms-wmx .wmx AddType application/x-ms-wmz .wmz AddType application/x-ms-wmd .wmd #skompresowane AddType application/zip .zip AddType application/x-gzip .gz AddType application/x-gtar .gtar AddType application/x-rar-compressed .rar AddType application/octet-stream .dmg AddType application/x-7z-compressed .7z #graficzne Addtype image/jpg .jpg Addtype image/gif .gif #pozostałe AddType application/x-bittorrent .torrent AddType application/vnd.rn-realmedia .rm AddType audio/vnd.rn-realaudio .ra .ram AddType video/vnd.rn-realvideo .rv
Możemy również wymusić na przeglądarce pobieranie plików zamiast ich automatycznego odczytywania:
AddType application/octet-stream .pdf .gz
Taki zapis spowoduje, że dokumenty w formacie .pdf oraz .gz będą pobierane, a nie otwierane przez domyślną aplikacje.
Warto wspomnieć o jeszcze jednej prostej, ale przydatnej opcji, której nie sposób pominąć. Edytując plik .htaccess, można szybko dokonać zmiany
kodowania dokumentów:
AddDefaultCharset ISO-8859-1 AddDefaultCharset ISO-8859-2
Subdomeny
Załóżmy, że dysponujemy utworzoną subdomeną www.sub.strona.pl. Zadanie będzie polegało na przekierowaniu jej na odpowiedni katalog przy użyciu pliku .htaccessa.
Zacznijmy od przekierowania subdomeny na odpowiedni katalog bez konieczności zaglądania do panelu administracyjnego domeny:
RewriteCond %{HTTP_HOST} sub.strona.pl
RewriteCond %{REQUEST_URI} !sub/
RewriteRule (.*) sub/ [L]
Ten zapis sprawi, że użytkownik, który wejdzie na adres www.sub.strona.pl, tak naprawdę zostanie przeniesiony na www.strona.pl/sub.
Jak powinien w takim razie wyglądać zapis, aby w pasku adresu zamiast {stala}www.strona.pl/sub{/stala} zobaczyć adres subdomeny {stala}www.sub.strona.pl?{/stala}
Umożliwi to dodanie do .htaccess kilku linijek kodu:
RewriteCond %{HTTP_HOST} www.strona.pl [NC]
RewriteCond %{REQUEST_URI} sub/
RewriteRule (.*) http://www.sub.strona.pl [L]
I gotowe. Teraz po wejściu do katalogu {stala}/sub{/stala} z pozycji przeglądarki, w pasku adresu zobaczymy www.sub.strona.pl. Jeżeli rzecz dotyczy kilku subdomen,
można teoretycznie powielać wpis w pliku .htaccess:
RewriteCond %{HTTP_HOST} sub.strona.pl
RewriteCond %{REQUEST_URI} !sub/
RewriteRule (.*) sub/ [L]
RewriteCond %{HTTP_HOST} sub2.strona.pl
RewriteCond %{REQUEST_URI} !sub2/
RewriteRule (.*) sub2/ [L]
Jednak przy większej liczbie adresów mija się to z celem. Warto wtedy skorzystać z wyrażeń regularnych i zastosować uniwersalny zapis, który
będzie pasował do wszystkich katalogów:
RewriteCond %{HTTP_HOST} strona.pl [NC]
RewriteCond %{HTTP_HOST} (.*).strona.pl [NC]
RewriteRule .* /%2%{REQUEST_URI}
Tak samo wygląda sprawa w drugą stronę.
Zamiast dodać wiele linijek zbędnego kodu, wystarczy stworzyć definicję, która obejmie wszystkie adresy. Dla przykładu:
RewriteCond %{HTTP_HOST} strona.pl [NC]
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule .* http://%1.strona.pl [L]
Druga linijka odpowiada za znalezienie jakiegoś znaku, czyli np. nazwy naszego katalogu z wcześniejszego przykładu. Należy zwrócić uwagę, że zastosowany został zapis (.+). Użycie w tym miejscu (.*) również dałoby efekt, ale napotkalibyśmy problemy przy wpisywaniu adresu strony głównej www.strona.pl, ponieważ taki zapis
dopuszcza również wstawienie pustego znaku.
Należy przy tym uwzględnić adresy z www i bez www. Z tego powodu do naszych zapisów dodamy warunek za to odpowiedzialny {stala}!^(www.)?{/stala}. Czyli ostateczny kod będzie następujący:
RewriteCond %{HTTP_HOST} !^(www.)?strona.pl$[NC]
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule .* http://%1.strona.pl [L]
Dzięki temu bez względu na to, czy wpiszemy {stala}http://www.strona.pl/sub/{/stala}, czy {stala}http://strona.pl/sub/{/stala}, adres w przeglądarce będzie zawsze miał postaćhttp://sub.strona.pl.
Zmienne globalne
Zmienne przeglądarki
• HTTP_USER_AGENT – identyfikator przeglądarki
• HTTP_REFERER – adres z przekierowania
• HTTP_HOST – adres hosta, który jest wywoływany
• HTTP_CONNECTION – tryb połączenia
• HTTP_COOKIE – zawiera cookie
• HTTP_ACCEPT – dokumenty jakie przyjmuje przeglądarka
• HTTP_ACCEPT_LANGUAGE – język przeglądarki
• HTTP_ACCEPT_ENCODING – czy przeglądarka akceptuje skompresowane pliki
• HTTP_ACCEPT_CHARSET – akceptowane kodowanie dokumentu
• HTTP_CONNECTION – tryb połączenia
Zmienne wywołania
• REMOTE_ADDR – adres IP użytkownika
• REMOTE – host użytkownika
• REMOTE_USER – nazwa użytkownika
• REMOTE_PORT – port wywołania
• AUTH_TYPE – rodzaj autoryzacji ( Basic/Digest)
Zmienne z informacją o działającym skrypcie
• SCRIPT_URL – adres logiczny (zmienna z informacją o skrypcie)
• SCRIPT_URI pełen adres wraz z hostem (zmienna z informacją o skrypcie)
• SCRIPT_FILNAME – nazwa pliku wraz ze ścieżka (zmienna z informacją o skrypcie)
• SCRIPT_NAME – nazwa skryptu
Zmienne z informacją o zapytaniu
• REQUEST_FILNAME – pełna ścieżka do pliku
• REQUEST_URI – zawiera pełen adres wywołania
Zmienne mod_rewrite
• QUERY_STRING – informacja o parametrach przesyłanych do skryptu
• THE_REQUEST – kompletne wysyłane zapytanie HTTP
Zmienne serwera
• SERVER_ADMIN – e-mail admina
• SERVER_NAME – adres serwera
• SERVER_ADDR – adres IP serwera
• SERVER_PORT – adres portu
• SERVER_ID – identyfikator
• SERVER_PROTOCOL – informacje o protokole (np.: zazwyczaj HTTP/1.1)
• DOCUMENT_ROOT – ścieżka do głównego katalogu
Zmienne związane z czasem
• TIME_YEAR – obecny rok
• TIME_MON – miesiąc
• TIME_DAY – dzień
• TIME_HOUR – godzina
• TIME_MIN – minuty
• TIME – aktualny czas w postaci yyyymmddhhmmss
Inne
• PATH_INFO zawiera dopełnienie ścieżki
• REDIRECT_URL oryginalny adres przed przekierowaniem
Blokowanie
Dostęp do strony można także z powodzeniem zablokować, stosując mod_rewrite. Jeśli masz podejrzenia, że pewne zasoby strony, np. grafiki lub style, są nielegalnie wykorzystywane przez inną witrynę, warto zablokować jej dostęp. Do pliku .htaccess należy dopisać:
RewriteCond %{HTTP_REFERER} niechciany.com [NC]
RewriteRule .* - [F]
W pierwszej linii wskazujemy adres, z którego nie życzymy sobie wejść na stronę. Druga linia odpowiada za wyświetlanie strony z błędem 403.
Dokładne znaczenie {stala}HTTP_REFERER{/stala} i innych zmiennych globalnych zostało zawarte w ramce.
MIME type w mod_rewrite
Zmiana sposobu odczytywania plików była już poruszana w tym artykule, warto jednak wspomnieć, że również przy użyciu mechanizmu mod_rewrite możliwe jest nadanie odpowiednich MIME Type. Do tej pory poznaliśmy metodę korzystającą z dyrektywy AddType:
AddType application/x-7z-compressed .7z
co oznaczało, że dla plików z rozszerzeniem .7z domyślną aplikacją jest 7-zip. W poniższym przykładzie zastosowana została dyrektywa RewriteRule,
która wszystkie pliki .php(s) będzie odczytywać jako .phps:
RewriteRule ^(.+.php)s$ [T=application/x-httpd-php-source]
Standardowo {stala}^ i ${/stala} wyznaczają początek i koniec zapisu, $1 to zmienna, a atrybut to {stala}[T=MIME type]{/stala}.
ForceType
Jeżeli zdarzy się, że mod_rewrite będzie wyłączony na naszym serwerze, wystarczy skorzystać z ForceType. Załóżmy, że zamiast {stala}www.strona.pl/index.php{/stala}, chcemy uzyskać {stala}www.strona.pl/index{/stala}.
W tym celu tworzymy w pliku .htaccess zapis:
DirectoryIndex index ForceType application/x-httpd-php
Pierwsza linia to omówione już wcześniej wskazanie domyślnego pliku startowego (przydaje się, gdy skasujemy rozszerzenie w pliku index. php). Dalej mamy zapis ForceType, który każdorazowo należy stworzyć:
Sposób odczytywania pliku
W naszym przykładzie chcemy, aby index był odczytywany jako plik index.php dlatego zastosowane zostało {stala}application/x-httpd-php{/stala}. Możemy również dodać definicję, która z góry narzuci zasadę, aby wszystkie pliki były odczytywane na przykład jako html:
ForceType text/html
Jak widać, przy użyciu ForceType w prosty i znacznie szybszy sposób niż mod_rewrite można operować przyjaznymi linkami i rozszerzeniami.
Inne opcje
Prostą, ale dosyć istotną dyrektywą jest Indexes.
Polega ona na zezwoleniu lub uniemożliwieniu przeglądania zawartości katalogów. Dla właścicieli stron lepiej by było, aby odwiedzający nie mieli możliwości swobodnego przeglądania zawartości katalogów. W tym celu do pliku .htaccess należy dopisać:
Options -Indexes
Jeśli dowolny użytkownik chciałby przejrzeć katalogi z poziomu przeglądarki, zobaczy komunikat:
„403 dostęp zabroniony”. Gdy jednak zajdzie potrzeba udostępnienia zawartości katalogów, wówczas wpis powinien wyglądać następująco:
Options +Indexes
Jak widać, w miejsce minusa wystarczy wstawić plus.
Można również zezwolić na przeglądanie zawartości katalogów, ale z pewnymi ograniczeniami.
W tym celu należy zastosować dyrektywę IndexIgnore, wymieniając rozszerzenia i ewentualne nazwy plików, których nie chcemy udostępniać:
Options +Indexes IndexIgnore *gif *jpg *.png .?* g*
Powyższy zapis spowoduje, że podczas oglądania danego katalogu nie będą widoczne pliki graficzne (GIF, JPG, PNG), jak również te zaczynające się od kropki (np. .htaccess) oraz na literę „g”.
Eksperymentuj do woli
To prawda, że plik .htaccess oferuje ogromne możliwości. Udowodniliśmy jednak, że do ich opanowania nie jest wymagana żadna wiedza tajemna. Wystarczy znajomość kilku podstawowych reguł i metaznaków, aby móc swobodnie zarządzać funkcjonowaniem adresów w serwisie internetowym. Jeżeli zaciekawił cię ten temat, zachęcamy do lektury pełnej dokumentacji serwera Apache (więcej na ten temat przeczytasz w ramce) i samodzielnego eksperymentowania z ustawieniami pliku .htaccess!
Hasła
Za pomocą pliku .htaccess można także ograniczyć dostęp do strony bądź danego katalogu tylko dla użytkowników, którzy będą znali login i hasło.
Aby ustawić loginy użytkowników i ich hasła, należy najpierw stworzyć plik .htpasswd. Wpisujemy w nim niezakodowany login, po nim znak dwukropka, a następnie zakodowane hasło. To bardzo ważne, hasło musi być zakodowane zgodnie z algorytmem MD5.
W celu jego wygenerowania można skorzystać z gotowych rozwiązań, np. z automatu dostępnego na stronie http://www.tools.dynamicdrive.com/password/. Innym dostępnym
generatorem online pliku .htpasswd jest http://www.htaccesstools.com/htpasswd-generator/.
Przykładowy plik .htpasswd powinien wyglądać następująco:
uzytkownik:zdSVMujsXokkE
Można stworzyć kilka loginów i haseł. Należy jednak pamiętać, aby każdy wpis zaczynał się od nowej linii. Dla przykładu:
uzytkownik1:jf05LdXAvmanY uzytkownik2:5z0GcRGJ.CitM uzytkownik3:rhGPWeaHukQb
Mamy już stworzony plik .htpasswd, teraz czas na odpowiedni zapis w pliku .htaccess:
AuthName "Strefa zaszyfrowana" AuthType Basic AuthUserFile /home/users/nazwakonta/public_html/joomla/.htpasswd AuthGroupFile /dev/null require valid-user
Linia AuthName odpowiada za nazwę zaszyfrowanego obszaru – ta nazwa będzie widoczna w okienku przy podawaniu loginu i hasła. Wartości AuthType i AuthGroupFile pozostają bez zmian, natomiast AuthUserFile powinno kierować do adresu, pod którym znajduje się plik .htpasswd, np.:
AuthUserFile /home/users/nazwakonta/public_html/joomla/.htpasswd
Ostatnia linia, czyli require valid-user, odpowiada za chroniony obszar. Jeśli cała strona ma być dostępna dopiero po wpisaniu hasła, wówczas pozostaje bez zmian, czyli:
require valid-user
Jeżeli jednak zamierzasz zabezpieczyć poszczególne pliki, wpis powinien zawierać dwie kolejne linie:
require valid-user
Czyli cały zapis będzie następujący:
AuthName "Strefa zaszyfrowana" AuthType Basic AuthUserFile /home/users/nazwakonta/public_html/joomla/.htpasswd AuthGroupFile /dev/null require valid-user
Zabezpieczając stronę hasłem, musimy pamiętać, że zadziała ono tylko wówczas, gdy użytkownik będzie korzystał z protokołu HTTP. Jeśli zdarzy się, że użyje połaczenia FTP, to takie zabezpieczenie nie będzie skuteczne.
Strony błędów
Dzięki edycji pliku .htaccess można także stworzyć własne strony błędów. Kody odpowiedzi HTTP są numerycznymi danymi wysyłanymi przez serwer do klienta. Kody informacyjne to 1XX, kody powodzenia to 2XX (np. kod 200), kody przekierowania zaczynają się od cyfry 3XX. My natomiast zajmiemy się kodami 4XX i 5XX – pierwsze są
odpowiedzią błędu aplikacji po stronie użytkownika, drugie błędu serwera.
Na początek warto przypomnieć komunikaty błędów – patrz tabela 1.
Tab. 1. Komunikaty błędów
kod znaczenie
400 Błędne zapytanie
401 Dostęp wymaga autoryzacji (np. hasło)
402 Wymagana opłata (obecnie niestosowane)
403 Zabroniony dostęp ze względu bezpieczeństwa
404 Nie znaleziono strony, najpopularniejszy komunikat
405 Niedozwolona metoda
406 Nie może zwrócić odpowiedzi
407 Wymagane uwierzytelnienie do serwera (podobne działanie jak 401)
408 Koniec czasu oczekiwania na zapytanie
409 Występowanie konfliktu między statusami zasobu
410 Usunięto zasób
411 Serwer odmawia realizacji ze względu na brak długości
412 Jeden z warunków jest nie do spełnienia
413 Zapytanie zbyt długie dla serwera
414 Adres URL za długi
415 Niezrozumiały komunikat dla serwera
416 Nie można obsłużyć zakresu zapytania
417 Oczekiwana wartość nie do zwrócenia
500 Wewnętrzny błąd serwera
501 Serwer nie może zwrócić odpowiedzi, ponieważ nie rozumie zapytania
502 Błąd bramy, niepoprawna odpowiedź od serwera nadrzędnego
503 Niedostępny, w danej chwili serwer jest przeciążony
504 Przekroczony czas bramy (brak odpowiedzi od nadrzędnego)
505 Nie obsługuje danej wersji HTTP
Definicja, którą należy wstawić do pliku .htaccess, aby zamienić standardową stronę błędu na nową, ogranicza się do jednej linii:
ErrorDocument 404 /errors/404.html
Ewentualnie można podać adres bezwzględny do pliku lub dokonać przekierowania na inną stronę:
ErrorDocument 404 http://www.magazynyinternetowe.pl
Jeśli nie chcesz tworzyć całej strony błędu, możesz również skorzystać z prostszego rozwiązania, czyli zdefiniować własny komunikat błędu. W tym
celu należy zapisać:
ErrorDocument 404 "Brak dokumentu na serwerze - przepraszamy"
Podsumowując, standardowe strony błędów możemy zastąpić na kilka sposobów:
ErrorDocument 401 /errors/401.html ErrorDocument 403 http://www.magazynyinternetowe.pl ErrorDocument 404 "Brak dokumentu na serwerze - przepraszamy"
Blokowanie dostępu
Ograniczenie dostępu do strony poprzez zastosowanie .htpassw to tylko jedna z możliwych metod. Możemy również blokować dostęp poszczególnym adresom IP lub ich całym grupom.
Może się to okazać przydatne przy różnego rodzaju ankietach lub przy kontrolowaniu działalności robotów internetowych.
Przykładowa konstrukcja zapisu powodująca zablokowanie dostępu z danego IP wygląda następująco:
deny from 123.456.789.000
W sytuacji, gdy chcemy zablokować dostęp wszystkim, na przykład do konkretnego katalogu, wystarczy wpisać:
deny from all
Można również zablokować dostęp wszystkim, poza wybranymi adresami. Wtedy zapis będzie następujący:
deny from all allow from 123.456.789.000
W tym przepadku pierwsza linia odpowiada za całkowite zablokowanie dostępu, a druga umożliwia dostęp z adresu 123.456.789.000. Istnieje również możliwość zablokowania dostępu całym grupom adresów. Warto pamiętać o parametrze order, za pomocą którego nadajemy kolejność przetwarzania wpisów:
Order allow, deny
Powyższy zapis oznacza, że wpierw wykonywane są warunki allow, czyli odpowiadające za dostęp, a dopiero potem te ograniczające czyli deny. Przykładowy zapis z użyciem parametru order wygląda następująco:
order allow, deny deny from 123.456.789 deny from 000.123.4 allow from all
Gdyby w powyższym fragmencie kodu nie było zapisu order allow, deny, fragment allow from all osłabiłby działanie wcześniejszych. A tak, mimo umieszczenia na końcu, dyrektywa zostanie wypełniona zgodnie z oczekiwaniami (brak dostępu dla wyszczególnionych adresów IP i brak ograniczeń dla reszty).
Dostęp można również zablokować dla poszczególnych hostów z konkretnej subdomeny lub całych domen. Wtedy zapis będzie podobny do poprzednich:
order allow, deny deny cos.domena.com deny domena.com allow from all
Moduł mod_rewrite jest dosyć popularny i niejednokrotnie okaże się przydatny. Warto upomnieć się o niego, jeśli z jakichś przyczyn został wyłączony przez administratora.
Bazuje on na definicjach wyrażeń regularnych zgodnych z PCRE (Perl Compatible Regular Expression).
W tabeli 2 przypominamy zastosowania podstawowych metaznaków.
Tab. 2. Metaznaki stosowane w wyrażenia regularnych
symbol znaczenie
. Dowolny znak
^ Oznacza początek napisu
$ Oznacznik końca (c$ znaczy, że ciąg tekstowy
musi zakończyć się na c)
+ Wystąpi jeden lub więcej razy
* Zero lub więcej wystąpień
? Zero lub jedno wystąpienie
! Negacja wyrażenia
( Rozpoczyna grupowanie (przetwarzanie ciągu
znaków, jakby był to pojedynczy element)
[ Rozpoczyna klasę znaków, np. dopasowane
do przedziału od 0 do 9, to definicja klasy
[0-9]
Nasz przykład rozpoczniemy od najprostszego
przepisania adresu. Poniższy zapis sprawi, że do
pliku index.php będzie można się odwołać, wpisując
adres standardowego pliku index.html:
Options FollowSymLinks RewriteEngine On RewriteRule ^index.html$ index.php [L]
Dwie pierwsze linie powodują aktywację mod-rewrite. Natomiast atrybut {stala}[L]{/stala} (od last rule) określa daną linię jako ostatnią, co oznacza, że reguły nie
będą dalej wykonywane.
Możemy również dodać atrybut {stala}[NC]{/stala}, który sprawi, że bez względu na to, czy adres wpisywany jest wielkimi, czy małymi literami, będzie
odczytany poprawnie. Dzięki temu {stala}IMAGES/2.jpg{/stala} będzie działać tak samo jak {stala}images/2.jpg{s/tala}.
Opis pozostałych atrybutów znajdziesz w ramce.
W zapisie pojawiają się jeszcze znaki {stala}^ i ${/stala}, będące tzw. metaznakami stosowanymi w wyrażeniach regularnych. Oznaczają one początek i koniec ciągu, po którym znajduje się wyraz index.html.
Sposób na metaznaki
Symbole . [ ^ $ | ( ) * + ? { to znaki o specjalnym
znaczeniu, stosowane w wyrażeniach
regularnych. Jeżeli potrzebujesz ich użyć jako
zwykłych znaków, bez ich funkcji, poprzedź je
backslashem .
Przyjazne linki
Przyjazne linki nie tylko poprawią skuteczność wyszukiwania naszych podstron przez boty wyszukiwarek, ale także ułatwiają korzystanie z serwisu użytkownikom.
Najprostsza zamiana linków występuje w przypadku, gdy mamy jedną zmienną. Adres {stala}www.strona.pl/artykul.php?id=2{/stala} będzie bardziej czytelny dla użytkownika i wyszukiwarki, gdy będzie następujący: {stala}www.strona.pl/artykul-2.html{/stala}. Aby tego dokonać, w pliku .htaccess wpisujemy:
RewriteRule ^artykul-([^-]+).html$artykul.php?id=
{stala}([^-]+){/stala} oznacza dowolny ciąg znaków złożony z przynajmniej jednego znaku bez myślnika (odpowiada za to zapis {stala}[^-]{/stala}, czyli każdy znak poza myślnikiem; gdyby nie symbol ^, temu zapisowi odpowiadałby tylko znak myślnika). Można go również zastąpić {stala}([0-9]+) lub (.*)){/stala}. Taki ciąg przenoszony jest do drugiej części reguły w miejsce $1.
Oczywiście fragment .html może zostać pominięty lub zastąpiony skrótem .htm – w zależności od potrzeb.
W regułach RewriteRule przed zmiennymi stoi znak $. Warto to zapamiętać, bo w regule Rewrite-Cond są one zapisywane ze znakiem procent %.
Podobnie będzie wyglądać sytuacja w przypadku kilku zmiennych w adresie. Dla przykładu jeden z artykułów na stronie opartej o CMS Joomla! wygląda następująco:
http://www/strona.pl/index.php?option=com_content&task=view&id=1&Itemid=26
Jest on długi i mało czytelny. Dlatego skorzystamy z następującego zapisu:
RewriteRule ([^-]+)/([^-]+)/([^-]+)/([^-]+).html$ index.php?option=&task=&id=&Itemid= [L]
Zapis ten bazuje na schemacie:
AllowOverride None
Stary adres w naszym przypadku miał 4 zmienne: {stala}zmienna1=com_content&zmienna2_vie-w&zmienna3=1$zmienna4=26{/stala} i zgodnie z tym zapisaliśmy stary adres, gdzie {stala}[^-]{/stala} oznacza ciąg znaków bez myślnika. Moglibyśmy również skorzystać z alternatywnego zapisu:
RewriteRule (com_content)/(view)/([^-]+)/([^-]+).html$ index.php?option=&task=&id=&Itemid= [L]
Bez względu na to, który zapis zastosujemy, nowy link będzie następujący:
{stala}http://www.strona.pl/com_content/view/1/26.html{/stala}
Należy pamiętać, że slash (/) można zamienić na przykład na myślniki, przecinki lub zapisać bez spacji. Poniżej prezentujemy zapis dla adresu składającego się z 5 zmiennych:
http://www.strona.pl/index.php?option=com_content&task=category§ionid=1&id=1&Itemid=2
z użyciem kilku omówionych sposobów zapisu:
RewriteRule ([^-]+)/(category)/([^-]+)-(.*)([0-9]+)$ index.php?option=&task=&sectionid=&id=&Itemid= [L]
Tak zdefiniowany odnośnik będzie prezentował się w sposób następujący:
http://www.strona.pl/com_content/category/1-12
Jeszcze jedną przydatną opcją przy tworzeniu przyjaznych URL-i może okazać się usuwanie identyfikatorów sesji. Jeśli system, z którego korzystasz, dodaje ciąg znaków sesji, tzw. „sid”, warto go ukryć. W innym przypadku nasze starania nad stworzeniem czystych linków okażą się niemiarodajne, ponieważ link będzie posiadał atrybut sesji np.:
{stala}www.strona.pl/index.php?sid=12d34g567nn890123456789098w76547.{/stala}
W celu jego ukrycia, do pliku .htaccess należy dopisać:
#po linijce Options FollowSymLinks php_flag session.use_trans_sid off
Przekierowania
Nie każdy zdaje sobie sprawę, że adresy {stala}http://www.strona.pl/{/stala} i {stala}http://strona.pl/{/stala} to z punktu widzenia wyszukiwarek dwa odrębne serwisy. Dlatego, aby uniknąć podpadnięcia duplicate content (czyli duplikowania treści, na co np. Google zwraca dużą uwagę), warto wybrać jeden z adresów, a drugi przekierować.
Przekierowanie z WWW na adres bez WWW:
RewriteCond %{HTTP_HOST} ^www.strona.com [NC]
RewriteRule ^(.*)$ http://strona.com/ [R=301,L]
Przekierowanie bez WWW na WWW:
RewriteCond %{HTTP_HOST} ^strona.com [NC]
RewriteRule ^(.*)$ http://www.strona.com/ [R=301,L]
Atrybut [NC] sprawia, że nie ma znaczenia wielkość użytych liter we wpisywanym adresie.
Identycznie należy postąpić w sytuacji, gdy ze starego adresu strony chcemy w bezpieczny sposób przekierować ruch na nowy. Wtedy zapis będzie następujący:
RewriteCond %{HTTP_HOST} ^stary_adres.com [NC, OR]
RewriteCond %{HTTP_HOST} ^www.stary_adres.com
RewriteRule ^(.*)$ http://www.nowy.com/ [R=301,L]
Za pomocą RewriteCond możemy również sprawdzić, czy adres nie prowadzi do pliku bądź katalogu:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteuRule .* index.html [L]
Pierwsza linia sprawdza, czy ścieżka nie prowadzi do pliku, druga sprawdza to samo pod kątem katalogu. Kod w trzeciej linii określa, że jeśli żaden plik nie zostanie odnaleziony (!-f), wówczas zostanie załadowany plik {stala}index.html{/stala}.
Wymuszanie adresu domeny z przedrostkiem „https://”
Przypadek ten jest bardzo ważny dla użytkowników korzystających z certyfikatu SSL. Za pomocą poniższego kodu jesteś w stanie wymusić adres z przedrostkiem „https://”, który wykorzystywany jest do bezpiecznego połączenia z serwerem (szyfrowanie SSL).
RewriteEngine On
RewriteCond %{HTTPS} !^on$
RewriteRule ^(.*)$ https://www.domena.pl/$1 [R=301,L]
Inne popularne przykłady przekierowań
Zabezpieczenie przed linkowaniem obrazków:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?twojadomena\.pl [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} ^http://.*$
RewriteRule \.(jpe?g|gif|bmp|png)$ /obrazki/kradziez.png [L]
Przekierowanie wielu domen na jeden adres:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?domena1.pl$ [OR]
RewriteCond %{HTTP_HOST} ^(www\.)?domena2.pl$
RewriteRule ^(.*)$ http://www.domena.pl/$1 [R=301,L]
Przekierowanie z jednego adresu do drugiego w ramach tej samej domeny:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?twojadomena\.pl$ [NC]
RewriteRule ^adres1(\/.*)?$ http://www.twojadomena.pl/adres2 [R=301,L]
Flagi modułu mod_rewrite
[R = kod] force redirec – pozwala na przekierowanie linku według podanej wartości
[QSA] query string append – powoduje dodanie na końcu całego zapytania query string
[L] last rule – ustanawia linijkę jako ostatnią, reguły nie będą dalej wykonywane
[NC] no case – ignoruje fakt, czy adres wpisywany jest wielkimi, czy małymi literami
[T = MIME type] force MIME type – ustawienie typu MIME
[F] force URL to be forbidden – zwraca błąd 403
[S=liczba] skip next rule(s) – pomija zapisaną liczbę reguł
[N] next round – przetwarzanie od początku
Pozostałe flagi zostały szczegółowo opisane w dokumentacji modułu mod_rewrite, dostępnej pod adresem http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html.
Nic nie stoi na przeszkodzie, aby dokonać też innych przekierowań. Załóżmy, że chcemy, aby internauta po kliknięciu na odnośniku http://www.strona.pl/informacje, zobaczył podstronę znajdującą się w innym katalogu, niż wskazywałby to adres. Najprościej będzie skorzystać z przekierowania:
Redirect /katalog http://www.strona.pl/plik.php
Zapis ten oznacza, że użytkownik wchodząc do katalogu {stala}http://www.strona.pl/informacje{/stala}, tak naprawdę zostanie przeniesiony na stronę {stala}http://www.strona.pl/plik.php{/stala}