Strona główna » Ranking Organiczny » Poskramiamy .htaccess – przekierowania i nie tylko

Poskramiamy .htaccess – przekierowania i nie tylko

by Bartek Krzemień dnia 13 grudnia 2007

in Ranking Organiczny

.htaccess to ciekawy plik, który pozwala nam kontrolować sporo rzeczy nieosiągalnych na pierwszy rzut oka. W przypadku SEO, .htaccess najczęściej używany jest do wzbogacenia witryny o tzw. cool URLs czyli ładnie wyglądające adresy. Zapraszam do przeczytania jak oprócz efektu Cool URL osiągnąć jeszcze kilka innych, nie mniej ciekawych :).

Cool URLs (clean URLs)

Efekt fajnych URLi możliwy jest tylko wtedy, gdy nasz serwer Apache posiada mod_rewrite (ważne: serwer Apache, nie MS IIS). Jeśli dana witryna ma mało przyjazny, trudny do zapamiętania system generowania linków wewnętrznych, możemy sprawić, że przyjmą one pożądaną przez nas postać. Wyobraźmy sobie, że mamy linki widoczne jako /index.php?strona=akwaria i chcemy zmienić je na /strona/akwaria/ lub po prostu /akwaria/. Choć linki zmienią postać, to tak naprawdę cały czas odwołujemy się do ich pierwotnej postaci. Różnica polega na tym, że robi to za nas serwer, i robi to w sposób niewidoczny.

# inicjujemy rewrite engine
RewriteEngine on
# dla przykładu z www.strona.pl/strona/akwaria/
RewriteRule ^strona/([^/.]+)/?$ index.php?strona=$1 [L]
# dla przykładu z www.strona.pl/akwaria/
RewriteRule ^/([^/.]+)/?$ index.php?strona=$1 [L]

Końcowy slash

Przepisując URLe w sposób podany powyżej należy pamiętać o slashach na końcu adresu. Aby upewnić się, że zawsze tam będą, stosujemy następujący zapis:

RewriteEngine on
# nie dodajemy nic jeśli żądany plik istnieje
RewriteCond %{REQUEST_FILENAME} !-f
# sprawdzamy czy dany URL nie ma slasha na końcu
RewriteCond %{REQUEST_URI} !(.*)/$
# jeśli nie ma, przepisujemy URL z przekierowaniem 301
RewriteRule ^(.*)$
http://%{HTTP_HOST}/$1/ [L,R=301]

Jedna rada – sprawdzenie poprawności przekierowań może być uciążliwe jeśli od razu zapiszemy je z flagą R=301 (która oznacza trwałe przekierowanie). Firefox zapamiętuje permanentnie przekierowane adresy w pamięci podręcznej, więc jeśli coś się zmieni w pliku .htaccess – Firefox nadal stosuje pierwotny efekt. Z tego powodu lepiej w fazie testowej użyć R=302, które oznacza przekierowanie czasowe. Działa identycznie jak 301, ale przeglądarka za każdym razem sprawdzi dokąd przekierowanie prowadzi :). Powyższy zapis umieszczamy w pliku przed zapisem z przykładu o Cool URLs.

Przekierowanie z www na bez www i vice versa

Nie wszyscy wiedzą, że adresy http://www.domena.pl/ i http://domena.pl/ to z punktu widzenia wyszukiwarek dwa odrębne serwisy. Aby uniknąć problemów z duplicate content, bardzo dobrym pomysłem jest wybranie tylko jednego adresu, i ustawienie przekierowania na drugim. Jak ustawić przekierowanie?

RewriteEngine on
# przekierowanie dla przykładu www -> bez www
RewriteCond %{HTTP_HOST} ^www.domena.pl$ [NC]
RewriteRule ^(.*)$ http://domena.pl/$1 [R=301,L]
# przekierowanie dla przykładu bez www -> www
RewriteCond %{HTTP_HOST} !^www.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

Przekierowanie na nową domenę

Zdarza się to rzadko, nie mniej zdarza się :). Jeśli przenosimy witrynę na nową domenę:

RewriteEngine On
RewriteRule ^(.*)$ http://www.nowadomena.pl/$1 [R=301,L]

Powyższy przykład zadziała tylko wtedy, jeśli struktura folderów nie uległa zmianie.

Zabezpieczanie folderu przed listowaniem plików

Jeśli w jakimś z folderów nie mamy pliku index.(html|htm|php), to serwer najczęściej pokaże listę wszystkich dostępnych plików. Dla części webmasterów może to być niepożądany efekt. Aby zabezpieczyć foldery przed ukazywaniem zawartości możemy więc albo utworzyć dziesiątki pustych plików index.html, albo dodać następujący wpis do .htaccess:

Options All -Indexes

Dedykowane strony dla błędów

Czasem zdarza się, że na witrynie występuje błąd. Najczęściej jest to błąd 404 file not found, rzadziej zdarzają się także np. wewnętrzne błędy serwera, oznaczane kodem 500. Dzięki odpowiednim wpisom w .htaccess możemy dla każdego błędu zdefiniować unikalną stronę z odpowiednim komunikatem:

# dla błędu 404
ErrorDocument 404 /nieznalezionopliku.html
# dla błędu 500
ErrorDocument 500 /bledy/500.html

Możliwe jest przypisanie stron dla następujących błędów:

  • 401 – Authorization Required (wymagana autoryzacja)
  • 400 – Bad request (niepoprawne żądanie)
  • 403 – Forbidden (dostęp zabroniony)
  • 500 – Internal Server Error (wewnętrzny błąd serwera)
  • 404 – File not found (nie znaleziono pliku)

Zabezpieczanie folderu hasłem

W trakcie prac nad witryną często dobrym pomysłem ograniczenie dostępu do wersji rozwojowej. Dzięki .htaccess możemy zabezpieczyć dostęp do danego folderu hasłem.

AuthType basic
AuthName "Witryna wymaga autoryzacji"
AuthUserFile /home/sciezka/.htpasswd
Require valid-user

Jak widać, tym razem odwołujemy się jeszcze do pliku .htpasswd. Ścieżka do pliku powinna być pełna. Zawartość stanowi zestawienie nazwa_użytkownika:hasło. Przykładowy listing pliku:

bartek:aGyShsiiEkuWk
kasia:aGaVpPSVCdcIs

Poszczególne pary nazwa_użytkownika:hasło powinny być zawsze jedna pod drugą. Całość wpisu można wygenerować z konsoli, jeśli mamy na danej maszynie zainstalowanego Apache’a (polecam manual polecenia htpasswd). Jeśli nie mamy programu lokalnie – nie trzeba rozpaczać. Z pomocą przychodzą liczne wersje online, jak na przykład ten generator htpasswd. A dla wybrednych – [htpasswd generator] :).

Po tych zabiegach folder jest zabezpieczony hasłem. Wymaga autoryzowania każdej sesji od wszystkich użytkowników. Istnieje jednakże możliwość zostawienia sobie furtki tylko dla nas.

AuthType basic
AuthName "Witryna wymaga autoryzacji"
AuthUserFile /home/sciezka/.htpasswd
AuthGroupFile /dev/null
Require valid-user
Deny from all
Allow from 111.222.33.44
Satisfy Any

Oczywiście w miejsce 111.222.33.44 należy wpisać własne IP :).

A jakie ciekawe triki z .htaccess znacie Wy? Zapraszam do zostawiania przykładów w komentarzach :).

{ 17 komentarze… przeczytaj je poniżej lub dodaj swój }

1 ike 14 grudnia 2007 o 00:42

clean urls – ok słyszałem. nice urls – też, ale cool urls? :-) wow.

2 Bartek Krzemień 14 grudnia 2007 o 00:46

@ike: Czasem mnie ponosi ;).

3 Speedy 14 grudnia 2007 o 09:09

Wrzuć na techbloga. :)

4 Cakper 2 stycznia 2008 o 09:12

ok moje „tricki” ;)

DirectoryIndex index.php?action=glowna glowna.php index.php index.html

Pozwala ustawic która podstrona ma być traktowana jako indeks

php_value upload_max_filesize 6M
php_value post_max_size 6M

pozwala ustawić max wielkość przesyłanego przez formularz pliku niezależnie od ustawień php.ini

php_flag session.use_trans_sid off

przydatne gdy skrypt używa sesji, a one psują nam linki generowane przez .htaccess – problem znika ;)

5 mike 23 lutego 2008 o 00:24

No to mamy tu niezbędnik ;) jednak mam wątpliwość czy jest sens przechodzić z zaindeksowanej już struktury odnośników generowanych dynamicznie na przyjazne? Czy za to też nie można oberwać jak za duplicate-content? Korzyść chyba tylko w przypadku rozbudowanych serwisów z problemami od strony indeksowania.

regards, mike

6 Cakper 5 marca 2008 o 18:50

Co do pytania czy jest sens to ja osobiście uważam, że jest (mam nadzieję, że nie muszę uzasadniać :) ), a co do duplicate content – oprócz rewrite robisz w htaccess również przekierowania + usuwasz z sitemapy wpisy z „bad” linkami i wstawiasz tylko te „cool” i powinno być imho po sprawie

Duplicate content mimo wszystko nie jest rzeczą codzienną na normalnych stronach (nienormalne są np spamerskie zaplecza) i żeby ten filtr złapać to trzeba się trochę postarać ;)

7 Kasia Bauer 2 kwietnia 2008 o 23:10

W momencie gdy będzie to przekierowanie 301 to znika problem duplicate content. Jeżeli chodzi o przeprowadzenie takiego procesu (tj. zmiana odnośników z generowanych dynamicznie na przyjazne) to jest jak najbardziej sensowny krok z punktu widzienia SEO. Myk polega też na tym, że taka struktura ułatwia indexację. Dlatego też ten post się tutaj pojawił :)

@Cakper
Problem duplicate content (zduplikowej treści) nie dotyczy tylko stron spamerskich, splogów itp. ale każdej witryny. Jeżeli wyszukiwarka wykryje parę mniejszych ich przypadków na witrynie to nie zostaniemy od razu wyrzuceni z indexu. Jednak możemy zebrać parę „minusów” u wyszukiwarki. Więcej podobnych błędów może być właśnie powodem dla którego nie plasujemy się tak wysoko jak byśmy mogli.

8 al 6 lipca 2008 o 20:47

Ew. copy&paste do edytora tekstu

9 whyyyyy 23 lipca 2008 o 13:22

Dlaczego ja nie mogę tego wydrukować bez drukowania całej strony. whyyyyyy!!! Tell me Whyyyyyyy!!!!

10 Kasia Bauer 10 sierpnia 2008 o 23:01

Niestety nie dostosowaliśmy layoutu do druku. Spróbuj wyłączyć obsługę styli w przeglądarce i wtedy wydrukować.

11 al 6 listopada 2008 o 20:47

Ew. copy&paste do edytora tekstu

12 de 28 lipca 2009 o 10:17

A jak zrobić, żeby:
+ www -> bez www
+ strona/katalog -> subdomena.strona
Zrobiłam:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^strona/katalog(.*) [NC]
RewriteRule ^(.*)$ subdomena.strona/$1 [R=301,L]

RewriteCond %{HTTP_HOST} ^www.strona(.*) [NC]
RewriteRule ^(.*)$ http://strona/$1 [R=301,L]

aczkolwiek działa tylko ta pierwsza część, z www, a ta z katalogiem już nie…

13 GoON 7 października 2009 o 06:52

Ponieważ robisz to w złą stronę. Najpierw usuwasz www, a potem przekierowujesz na subdomenę z katalogu. Poniżej masz gotowca:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteCond %{HTTP_HOST} ^(.*)$ [NC]
RewriteRule ^(.*)$ http://strona.pl/$1 [R=301,NC,L,QSA]
RewriteCond %{HTTP_HOST} strona.pl [NC]
RewriteCond %{REQUEST_URI} katalog/
RewriteRule (.*) http://subdomena.strona.pl [R=301,NC,L,QSA]

Ostatni też miałęm z tym problemy i póki nie dodałem przekierowania z katalogu na subdomenę bez www, to z subdomeny z www na początku przekierowywało mnie na główną domenę pod wsazany katalog. Możesz sprawdzić dziaanie u mnie (subdomena to forum.lycans.pl)

14 kaprys 28 października 2009 o 18:02

A jak zrobic zebym tylko ja (wlasciciel) widzial prawdziwy index i inne pliki, a jak ktos obcy wejdzie to przekieruje go np. do pliku gosc.html.
Najlepiej po adresie IP, wtedy ja bym mial pelna kontrole nad serwisem (moglbym ogladac wszystkie strony, a gosc tylko jakis plik z info ze to nie dla niego )

15 Bartek Krzemień 28 października 2009 o 22:19

@kaprys
dla konkretnego pliku możesz na przykład zrobić to tak:

<Files "index.php">
  Order Deny,Allow
  Deny from all
  Allow from 123.123.123.123
  Satisfy any
 </Files>

Wtedy to IP z allow ma pełny odczyt, a reszta widzi stronę, którą ustawisz odpowiednim parametrem dla ErrorDocument.

Oczywiście zamiast jednego pliku możesz stworzyć dopasowanie np. dla danego rozszerzenia plików i tak dalej.

16 Magda 8 grudnia 2009 o 11:08

mam taki problem próbuje zastosować na serwisie proponowany przez was cool url i wszystko działa ale do czasu 9 zmiennej :/ zmienne 10 i więcej już nie przesyłają się tak jak powinny tylko przesyłane są kolejne liczby to jest 10, 11, 12 itd jako wartość zmiennej :/ Czy to wina serwera? Czy cool url ma jakieś ograniczenie gdzie to się ustawia?

chodzi mi o to że jak jest np.
index.php?a=$1&b=$2&c=$3&d=$4&e=$5&f=$6&g=$7&h=$8&i=$9&j=$10

to już nie działa tak jak powinno :/

17 Paolo 9 kwietnia 2010 o 13:25

Witam
A jak w .htacces, zrobić tak aby:
http://www.domena.com
http://www.domena.net
(bez www również) wskazywała na http://www.domena.pl ?
Kombinuje i nic mi nie wychodzi.

Chciałbym aby również, np po podaniu link w postaci http://www.domena.com/index.php?atrybut=43
automatycznie zmieniło się na http://www.domena.pl/index.php?atrybut=43

Proszę o pomoc

Zostaw Komentarz

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Wcześniejszy wpis:

Kolejny wpis