Wydaje się, że mod_rewrite
ostatnio pojawia się przyzwoita liczba wątków z pewnym zamieszaniem co do tego, jak działają niektóre aspekty. W rezultacie zebrałem kilka uwag na temat typowych funkcji i być może kilka irytujących niuansów.
Jakie inne funkcje / typowe problemy napotkałeś podczas używania mod_rewrite
?
apache
.htaccess
mod-rewrite
Owen
źródło
źródło
Odpowiedzi:
Gdzie umieścić zasady mod_rewrite
mod_rewrite
reguły mogą być umieszczone whttpd.conf
pliku lub w.htaccess
pliku. jeśli masz dostęphttpd.conf
, umieszczenie reguł w tym miejscu przyniesie korzyści wydajnościowe (ponieważ reguły są przetwarzane raz, a nie za każdym razem, gdy.htaccess
plik jest wywoływany).Rejestrowanie żądań mod_rewrite
Logowanie można włączyć z poziomu
httpd.conf
pliku (w tym<Virtual Host>
):Typowe przypadki użycia
Aby skierować wszystkie żądania do jednego punktu:
Od Apache 2.2.16 możesz również używać
FallbackResource
.Obsługa przekierowań 301/302:
Uwaga : przekierowania zewnętrzne to niejawnie przekierowania 302:
Wymuszanie SSL
Wspólne flagi:
[R]
lub[redirect]
- wymuś przekierowanie (domyślnie tymczasowe przekierowanie 302)[R=301]
lub[redirect=301]
- wymuś trwałe przekierowanie 301[L]
lub[last]
- zatrzymaj proces przepisywania (patrz uwaga poniżej dotycząca typowych pułapek)[NC]
lub[nocase]
- określ, że dopasowanie powinno nie uwzględniać wielkości literUżywanie długich flag jest często bardziej czytelne i pomoże innym, którzy przyjdą później przeczytać Twój kod.
Możesz oddzielić wiele flag przecinkami:
Typowe pułapki
Mieszanie
mod_alias
przekierowań zmod_rewrite
Uwaga : można zmieszać
mod_alias
zmod_rewrite
, ale to wymaga więcej pracy niż tylko podstawowe obsługi przekierowań jak wyżej.Kontekst wpływa na składnię
W
.htaccess
plikach wiodący ukośnik nie jest używany we wzorcu RewriteRule:[L] nie jest ostatni! (czasami)
[L]
Flag przestaje przetwarzać żadnych dalszych reguły przepisywania przez które przechodzą przez zestaw reguł . Jeśli jednak adres URL został zmodyfikowany w tym przebiegu i znajdujesz się w.htaccess
kontekście lub<Directory>
sekcji, to zmodyfikowane żądanie zostanie ponownie przekazane przez mechanizm analizy adresów URL. A przy następnym podaniu może tym razem pasować do innej reguły. Jeśli tego nie rozumiesz, często wygląda na to, że twoja[L]
flaga nie przyniosła żadnego efektu.Nasz dziennik przepisywania pokazuje, że reguły są uruchamiane dwukrotnie, a adres URL jest aktualizowany dwukrotnie:
Najlepszym sposobem obejścia tego jest użycie
[END]
flagi ( patrz dokumentacja Apache ) zamiast[L]
flagi, jeśli naprawdę chcesz zatrzymać dalsze przetwarzanie reguł (i kolejne przebiegi). Jednak[END]
flaga jest dostępna tylko dla Apache v2.3.9 + , więc jeśli masz wersję 2.2 lub niższą, utkniesz tylko z[L]
flagą.W przypadku wcześniejszych wersji musisz polegać na
RewriteCond
instrukcjach, aby zapobiec dopasowaniu reguł w kolejnych przebiegach mechanizmu analizowania adresów URL.Lub musisz upewnić się, że reguły RewriteRule znajdują się w kontekście (tj.
httpd.conf
), Który nie spowoduje ponownego przeanalizowania żądania.źródło
[L]
Flaga oznacza zasada jest ostatni w bieżącym przetwarzania, to nie zatrzyma przepisywania, bo są przekierowania wewnętrzne, więcdirB
stosuje siędirC
w następnym przetwarzania htaccess. SamodzielnieRewriteRule ^(.*)$ index.php?query=$1
będzie nieskończoną pętlą wewnętrznych przekierowań (w praktyce jest kończona po 10 iteracjach). -1, ponieważ sugerujesz, że [L] nie jest ostatnim . Nie kończy procesu przepisywania, ale jest ostatnia .RewriteCond %{HTTPS} off
jest to preferowany sposób sprawdzania połączenia HTTPS (w Twoim przykładzie wymuszania ruchu niezwiązanego z protokołemjeśli chcesz `` zablokować '' wewnętrzne przekierowania / przepisywanie z pliku .htaccess, spójrz na
stan, jak omówiono tutaj .
źródło
.*
z[L]
flagą czytałem przed mam tutaj.200
,!=200
,^.
,^$
. Najwyraźniej zmienna zostaje ustawiona200
na przekierowanie, ale także inne strony (z błędami i tym podobne) ustawiają ją na jakąś wartość. Teraz to znaczy, że albo sprawdzić, czy tois empty
,is not empty
,is 200
lubis not 200
, w zależności od tego, co trzeba.Umowa z RewriteBase:
Prawie zawsze musisz ustawić RewriteBase. Jeśli tego nie zrobisz, apache zgaduje, że twoją bazą jest fizyczna ścieżka dysku do twojego katalogu. Więc zacznij od tego:
źródło
RewriteBase .
lub coś wskazującego, że powinien zachować ten sam adres URL, zmieniając tylko to, co określono?RewriteBase
wtedy, gdy używasz względnego zastępowania ścieżki wRewriteRule
dyrektywie. Lepiej jest unikać używania ścieżek względnych.RewriteBase
całkowicie unikamy, ponieważ prawie wszyscy programiści źle rozumieją, co robi. Jak powiedział @ w3d, potrzebujesz go tylko wtedy, gdy chcesz zapisać znaki i chcesz zastosować tę samą bazę do wszystkich swoich Reguł RewriteRules w jednym pliku. Twój kod będzie prawdopodobnie bardziej zrozumiały dla innych, jeśli go unikniesz.Inne pułapki:
1- Czasami warto wyłączyć MultiViews
Nie jestem dobrze zorientowany we wszystkich możliwościach MultiViews, ale wiem, że psuje moje reguły mod_rewrite, gdy jest aktywny, ponieważ jedną z jego właściwości jest próba „zgadnięcia” rozszerzenia pliku, którego według niego szukam .
Wyjaśnię: załóżmy, że masz 2 pliki php w swoim katalogu internetowym, plik1.php i plik2.php i dodajesz te warunki i regułę do swojego .htaccess:
Zakładasz, że wszystkie adresy URL, które nie pasują do pliku lub katalogu, zostaną przechwycone przez plik1.php. Niespodzianka! Ta reguła nie jest honorowana dla adresu URL adresu http: // mojhost / plik2 / somepath . Zamiast tego zostajesz przeniesiony do pliku2.php.
Chodzi o to, że MultiViews automagicznie odgadło, że adres URL, którego faktycznie potrzebujesz, to http: //myhost/file2.php/somepath i chętnie Cię tam zaprowadził.
Teraz nie masz pojęcia, co się właśnie wydarzyło, i w tym momencie kwestionujesz wszystko, co myślałeś, że wiesz o mod_rewrite. Następnie zaczynasz bawić się regułami, próbując zrozumieć logikę stojącą za tą nową sytuacją, ale im więcej testujesz, tym mniej ma to sensu.
Ok, w skrócie, jeśli chcesz, aby mod_rewrite działał w sposób zbliżony do logiki, wyłączenie MultiViews jest krokiem we właściwym kierunku.
2- Włącz FollowSymlinks
Nie znam szczegółów tego, ale widziałem go wielokrotnie, więc po prostu zrób to.
źródło
+FollowSymLinks
jest wymieniony w dokumentacji jako obowiązkowy,mod_rewrite
aby w ogóle pracować, z niejasnych względów bezpieczeństwa.Równanie można wykonać na następującym przykładzie:
Dynamiczne równoważenie obciążenia:
Jeśli używasz mod_proxy do zrównoważenia systemu, możesz dodać dynamiczny zakres serwera roboczego.
źródło
Konieczne jest lepsze zrozumienie flagi [L]. Flaga [L] jest ostatnia, musisz tylko zrozumieć, co spowoduje, że Twoje żądanie zostanie ponownie skierowane przez silnik analizujący adresy URL. Z dokumentacji ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (wyróżnienie moje):
Zatem flaga [L] nie przestaje przetwarzać dalszych reguł przepisywania dla tego przebiegu przez zestaw reguł. Jeśli jednak reguła oznaczona [L] zmodyfikowała żądanie i znajdujesz się w kontekście .htaccess lub
<Directory>
sekcji, to zostanie ponownie przekazane przez mechanizm analizy adresów URL. A przy następnym podaniu może tym razem pasować do innej reguły. Jeśli nie rozumiesz, co się stało, wygląda na to, że twoja pierwsza reguła przepisywania z flagą [L] nie przyniosła żadnego efektu.Najlepszym sposobem obejścia tego jest użycie flagi [END] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) zamiast flagi [L], jeśli naprawdę chcesz przestać dalsze przetwarzanie reguł (i późniejsze naprawy). Jednak flaga [END] jest dostępna tylko dla Apache v2.3.9 +, więc jeśli masz wersję 2.2 lub starszą, utkniesz tylko z flagą [L]. W takim przypadku należy polegać na instrukcjach RewriteCond, aby zapobiec dopasowaniu reguł w kolejnych przebiegach mechanizmu analizowania adresów URL. Lub musisz upewnić się, że Twoja Reguła RewriteRule znajduje się w kontekście (np. Httpd.conf), który nie spowoduje ponownego przeanalizowania żądania.
źródło
Kolejną świetną funkcją są rozszerzenia mapy-przepisywania. Są szczególnie przydatne, jeśli masz ogromną liczbę hostów / przeróbek do obsłużenia:
Są jak klucz-wartość-zamiennik:
Następnie możesz użyć mapowania w swoich regułach, takich jak:
Więcej informacji na ten temat można znaleźć tutaj:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
źródło
.htaccess
przepisywania opartego na zasadach. To nie działa w tym kontekście.mod_rewrite może modyfikować aspekty obsługi żądań bez zmiany adresu URL, np. ustawianie zmiennych środowiskowych, ustawianie plików cookie itp. Jest to niezwykle przydatne.
Warunkowo ustaw zmienną środowiskową:
Zwróci odpowiedź 503:
RewriteRule
„s[R]
flag może przyjmować wartość non-3xx i zwracają non-przekierowanie odpowiedzi, np zarządzanej przestojów / konserwacji:zwróci odpowiedź 503 (a nie przekierowanie jako takie ).
Ponadto mod_rewrite może działać jak interfejs o dużej mocy dla mod_proxy, więc możesz to zrobić zamiast pisać
ProxyPass
dyrektywy:Opinia: używając
RewriteRule
s iRewriteCond
s do kierowania żądań do różnych aplikacji lub modułów równoważenia obciążenia w oparciu o praktycznie każdy możliwy aspekt żądania jest po prostu niezwykle potężne. Kontrolowanie żądań w drodze do zaplecza i możliwość modyfikowania odpowiedzi w drodze powrotnej sprawia, że mod_rewrite jest idealnym miejscem do centralizacji całej konfiguracji związanej z routingiem.Poświęć trochę czasu, aby się tego nauczyć, naprawdę warto! :)
źródło