To jest kanoniczne pytanie o mod_rewrite Apache.
Zmiana adresu URL żądania lub przekierowanie użytkowników na inny adres URL niż pierwotnie żądany odbywa się za pomocą mod_rewrite. Obejmuje to takie rzeczy jak:
- Zmiana HTTP na HTTPS (lub na odwrót)
- Zmiana żądania na stronę, która już nie istnieje, na nowy zamiennik.
- Modyfikacja formatu adresu URL (np.? Id = 3433 na / id / 3433)
- Prezentacja innej strony opartej na przeglądarce, na podstawie strony odsyłającej, na podstawie wszystkiego, co możliwe pod księżycem i słońcem.
- Wszystko, co chcesz zadzierać z adresem URL
Wszystko, co chciałeś wiedzieć o zasadach Mod_Rewrite, ale bałeś się zapytać!
Jak mogę zostać ekspertem w pisaniu reguł mod_rewrite?
- Jaki jest podstawowy format i struktura reguł mod_rewrite?
- Jakiej formy / smaku wyrażeń regularnych potrzebuję, aby dobrze zrozumieć?
- Jakie są najczęstsze błędy / pułapki podczas pisania reguł przepisywania?
- Jaka jest dobra metoda testowania i weryfikacji reguł mod_rewrite?
- Czy są jakieś konsekwencje SEO lub wydajności reguł mod_rewrite, o których powinienem wiedzieć?
- Czy zdarzają się często sytuacje, w których mod_rewrite może wydawać się odpowiednim narzędziem do pracy, ale tak nie jest?
- Jakie są najczęstsze przykłady?
Miejsce na sprawdzenie swoich zasad
Witryna testera htaccess to świetne miejsce do zabawy z regułami i ich testowania. Pokazuje nawet dane wyjściowe debugowania, dzięki czemu można zobaczyć, co pasowało, a co nie.
apache-2.2
mod-rewrite
redirect
redirection
301-redirect
Kyle Brandt
źródło
źródło
mod-rewrite
wyszukiwania tagów / filtrów.Odpowiedzi:
kolejność składni mod_rewrite
mod_rewrite ma pewne szczególne reguły porządkowania, które wpływają na przetwarzanie. Zanim cokolwiek zostanie zrobione,
RewriteEngine On
należy podać dyrektywę, ponieważ włącza to przetwarzanie mod_rewrite. Powinno to nastąpić przed innymi dyrektywami przepisującymi.RewriteCond
poprzedzanieRewriteRule
powoduje, że JEDNA reguła podlega warunkom. Wszelkie poniższe RewriteRules będą przetwarzane tak, jakby nie podlegały warunkom.W tym prostym przypadku, jeśli strona odsyłająca HTTP pochodzi z serverfault.com, przekieruj żądania bloga na specjalne strony z błędami serwera (jesteśmy po prostu wyjątkowi). Jeśli jednak powyższy blok miał dodatkową linię RewriteRule:
Wszystkie pliki .jpg trafiałyby na specjalne strony błędów serwera, nie tylko te z odsyłaczem wskazującym, że pochodzą stąd. Wyraźnie nie jest to celem pisania tych zasad. Można to zrobić za pomocą wielu reguł RewriteCond:
Ale prawdopodobnie należy to zrobić przy użyciu nieco trudniejszej składni zastępczej.
Bardziej złożona RewriteRule zawiera warunki do przetwarzania. Ostatni w nawiasach
(html|jpg)
mówi RewriteRule, aby pasował do jednegohtml
lubjpg
, i reprezentował dopasowany ciąg jako 2 $ w przepisanym ciągu. Jest to logicznie identyczne z poprzednim blokiem, z dwiema parami RewriteCond / RewriteRule, po prostu robi to w dwóch liniach zamiast czterech.Wiele linii RewriteCond jest domyślnie ANDed i może być jawnie ORed. Aby obsłużyć strony odsyłające zarówno w przypadku błędu serwera, jak i superużytkownika (jawne LUB):
Aby obsługiwać strony, o których mowa w ServerFault, w przeglądarkach Chrome (domyślnie AND):
RewriteBase
jest również specyficzny dla zamówienia, ponieważ określa, w jaki sposób następująceRewriteRule
dyrektywy obsługują ich przetwarzanie. Jest to bardzo przydatne w plikach .htaccess. Jeśli jest używana, powinna to być pierwsza dyrektywa pod „RewriteEngine on” w pliku .htaccess. Weź ten przykład:Mówi to mod_rewrite, że ten konkretny adres URL, który obecnie obsługuje, został dostarczony za pośrednictwem http://example.com/blog/ zamiast fizycznej ścieżki katalogu (/ home / $ Username / public_html / blog) i odpowiednio go traktować. Z tego powodu
RewriteRule
uważa, że ciąg znaków zaczyna się od „/ blog” w adresie URL. Oto ta sama rzecz napisana na dwa różne sposoby. Jeden z RewriteBase, drugi bez:Jak widać,
RewriteBase
pozwala przepisać reguły, aby wykorzystać ścieżkę witryny do treści zamiast do serwera , co może uczynić je bardziej zrozumiałymi dla tych, którzy edytują takie pliki. Mogą także skracać dyrektywy, co ma walory estetyczne.RewriteRule dopasowywanie składni
Sam RewriteRule ma złożoną składnię do dopasowywania ciągów. Omówię flagi (takie jak [PT]) w innej sekcji. Ponieważ Sysadmini uczą się na przykładach częściej niż czytając stronę podręcznika, podam przykłady i wyjaśnię, co robią.
.*
Konstrukcja pasuje do każdego pojedynczego znaku (.
) zero lub więcej razy (*
). Zamknięcie go w nawiasie nakazuje podanie ciągu, który został dopasowany jako zmienna 1 $.W tym przypadku pierwszy. * NIE został ujęty w parens, więc nie jest dostarczany do przepisanego łańcucha. Ta reguła usuwa poziom katalogu na nowej stronie blogu. (/blog/2009/sample.html zmienia się na /newblog/sample.html).
W takim przypadku pierwsze wyrażenie w nawiasie tworzy dopasowaną grupę. Staje się to 1 USD, co nie jest potrzebne i dlatego nie jest używane w przepisanym ciągu.
W tym przypadku używamy 1 $ w przepisanym ciągu.
Ta reguła używa specjalnej składni nawiasów, która określa zakres znaków . [0–9] odpowiada cyfrom od 0 do 9. Ta konkretna reguła będzie obsługiwać lata od 2000 do 2099.
Działa to tak samo jak poprzednia reguła, ale część {2} każe dwa razy dopasować poprzedni znak (w tym przypadku wyrażenie w nawiasie).
Ten przypadek będzie pasował do każdej małej litery w drugim dopasowanym wyrażeniu i zrobi to dla jak największej liczby znaków.
\.
Konstrukt informuje go traktować jako okres rzeczywistego okresu, a nie znak specjalny to w poprzednich przykładach. Jednak pęknie, jeśli nazwa pliku zawiera myślniki.Przechwytuje nazwy plików z myślnikami. Ponieważ jednak
-
jest znakiem specjalnym w wyrażeniach w nawiasach, musi być pierwszym znakiem w wyrażeniu.Ta wersja przechwytuje każdą nazwę pliku z literami, cyframi lub
-
znakiem w nazwie pliku. W ten sposób określasz wiele zestawów znaków w wyrażeniu nawiasowym.Flagi RewriteRule
Flagi reguł przepisywania mają wiele specjalnych znaczeń i przypadków użycia .
Flaga znajduje się
[L]
na końcu powyższego wyrażenia. Można użyć wielu flag oddzielonych przecinkiem. Dokumentacja powiązana opisuje każdą z nich, ale tutaj i tak są:L = ostatni. Przestań przetwarzać RewriteRules, gdy ten pasuje. Zamówienie się liczy!
C = łańcuch. Kontynuuj przetwarzanie następnej reguły RewriteRule. Jeśli ta reguła nie pasuje, następna reguła nie zostanie wykonana. Więcej na ten temat później.
E = Ustaw zmienną środowiskową. Apache ma różne zmienne środowiskowe, które mogą wpływać na zachowanie serwera WWW.
F = zabronione. Zwraca błąd 403, jeśli ta reguła jest zgodna.
G = Przeminęło. Zwraca błąd 410-Gone, jeśli reguła jest zgodna.
H = Handler. Wymusza obsługę żądania tak, jakby to był określony typ MIME.
N = Dalej. Wymusza regułę, aby zacząć od nowa i dopasować ponownie. BĄDŹ OSTROŻNY! Mogą wystąpić pętle.
NC = bez sprawy. Pozwala
jpg
aby dopasować zarówno jpg, jak i JPG.NE = Brak ucieczki. Zapobiega przepisywaniu znaków specjalnych (.? # I itp.) Na ich odpowiedniki w kodzie szesnastkowym.
NS = Brak żądań podrzędnych. Jeśli używasz dołączeń po stronie serwera, zapobiegnie to dopasowaniu do dołączonych plików.
P = Proxy. Wymusza obsługę reguły przez mod_proxy. Przejrzyste dostarczanie treści z innych serwerów, ponieważ Twój serwer internetowy pobiera je i ponownie obsługuje. Jest to niebezpieczna flaga, ponieważ źle napisana zmieni Twój serwer internetowy w otwarty serwer proxy i to jest złe.
PT = przejście. Uwzględnij instrukcje Alias w dopasowaniu RewriteRule.
QSA = QSAppend. Gdy oryginalny ciąg zawiera zapytanie ( http://example.com/thing?asp=foo) dołącz oryginalny ciąg zapytania do przepisanego ciągu. Zwykle byłby odrzucony. Ważne w przypadku treści dynamicznych.
R = Przekierowanie. Podaj przekierowanie HTTP na podany adres URL. Może również podać dokładny kod przekierowania [R = 303]. Bardzo podobny do
RedirectMatch
, który jest szybszy i powinien być używany, gdy to możliwe.S = Pomiń. Pomiń tę zasadę.
T = typ. Podaj typ MIME zwracanej treści. Bardzo podobny do
AddType
dyrektywy.Wiesz, jak powiedziałem, że
RewriteCond
dotyczy jednej i tylko jednej reguły? Możesz to obejść, łącząc łańcuchy.Ponieważ pierwsza RewriteRule ma flagę Łańcuch, druga reguła przepisywania zostanie wykonana, gdy zrobi to pierwsza, czyli wtedy, gdy dopasowana zostanie poprzednia reguła RewriteCond. Przydatne, jeśli wyrażenia regularne Apache powodują ból mózgu. Jednak metoda „wszystko w jednym wierszu”, którą wskazuję w pierwszej sekcji, jest szybsza z punktu widzenia optymalizacji.
Można to uprościć za pomocą flag:
Ponadto niektóre flagi dotyczą również RewriteCond. W szczególności NoCase.
Dopasuje „ServerFault.com”
źródło
mod_rewrite
i regularny podkład. +1.RewriteCond
jest rzeczywiście przetwarzane poRewriteRule
jest dopasowany. Możesz chcieć powiedzieć „więcej na ten temat później” u góry, gdzie mówisz „RewriteCond poprzedzający RewriteRule powoduje, że JEDNA reguła podlega warunkom”. Warto wspomnieć, że wyrażenia regularne są wyrażeniami regularnymi zgodnymi z Perl. Poza tym masz obcą apostrof w „... RewriteRule uważa, że to początek łańcucha…”RewriteRule ^/blog/.*/(.*)$ /newblog/$1
nie pasuje do pierwszego komponentu katalogu - przepisywanie jest domyślnie zachłanne. /.*/(.*) pasuje zarówno do / 1 / (2) / i / 1/2/3/4/5 / (6) /, więc potrzebujesz / [^ /] * /, aby dopasować tylko PIERWSZĄ ścieżkę składnik.Odłożę się do doskonałej odpowiedzi sysadmin1138 na te kwestie.
Oprócz kolejności składni, dopasowywania / wyrażeń regularnych i flag RewriteRule opisanych przez sysadmin1138, uważam, że należy wspomnieć, że mod_rewrite ujawnia zmienne środowiskowe Apache oparte na nagłówkach żądań HTTP i konfiguracji Apache.
Polecam AskApache za mod_rewrite Debug Tutorial dla Pełną listę zmiennych, które mogą być dostępne do mod_rewrite.
Większość problemów z RewriteRule wynika z niezrozumienia składni PCRE / nieprawidłowego unikania znaków specjalnych lub braku wglądu w zawartość zmiennych używanych do dopasowywania.
Typowe problemy i zalecane rozwiązywanie problemów:
IfModule
warunkowo, aby uniknąć tego scenariusza), sprawdź składnię dyrektywy, komentuj dyrektywy aż do zidentyfikowania problemuNajpierw spójrz na zawartość zmiennych środowiskowych, które chcesz dopasować - jeśli masz zainstalowany PHP, jest to tak proste, jak dodanie następującego bloku do aplikacji:
... następnie napisz swoje reguły (najlepiej do testowania na serwerze programistycznym) i zanotuj niespójne dopasowanie lub aktywność w pliku Apache ErrorLog .
W przypadku bardziej złożonych reguł użyj
RewriteLog
dyrektywy mod_rewrite, aby zarejestrować działanie w pliku i ustawićRewriteLogLevel 3
AllowOverride all
wpływa na wydajność serwera, ponieważ Apache musi sprawdzać.htaccess
pliki i analizować dyrektywy przy każdym żądaniu - jeśli to możliwe, zachowaj wszystkie dyrektywy w konfiguracji VirtualHost dla swojej witryny lub włącz.htaccess
przesłonięcia tylko tych katalogów, które ich potrzebują.Wskazówki Google dla webmasterów jednoznacznie stwierdzają: „Nie wprowadzaj użytkowników w błąd ani nie prezentuj wyszukiwarkom innych treści niż wyświetlasz użytkownikom, co jest powszechnie określane jako„ maskowanie ”” - unikaj tworzenia dyrektyw mod_rewrite filtrujących roboty wyszukiwarek.
Roboty wyszukiwarek preferują treść 1: 1: mapowanie URI (jest to podstawa do rankingu linków do treści) - jeśli używasz mod_rewrite do tworzenia tymczasowych przekierowań lub podajesz tę samą treść pod wieloma identyfikatorami URI, rozważ podanie kanonicznego identyfikatora URI w obrębie twoje dokumenty HTML.
To ogromny (i potencjalnie kontrowersyjny) temat sam w sobie - lepiej (IMHO) zajmować się poszczególnymi przypadkami i pozwolić pytającym ustalić, czy proponowane rozwiązania są odpowiednie do ich potrzeb.
Mod_rewrite w Ask_Apps Tricks and Tips obejmuje prawie każdy typowy przypadek użycia, który pojawia się regularnie, jednak „prawidłowe” rozwiązanie dla danego użytkownika może zależeć od złożoności konfiguracji użytkownika i istniejących dyrektyw (dlatego jest to ogólnie rzecz biorąc dobry pomysł, aby zobaczyć, jakie inne dyrektywy użytkownik ma na miejscu, gdy pojawia się pytanie mod_rewrite).
źródło
Redirect
lubRedirectMatch
zamiast. Zobacz także dokumenty Apache: Kiedy nie używać mod_rewriteJak wielu administratorów / programistów od lat walczę ze złożonością reguł przepisywania i jestem niezadowolony z istniejącej dokumentacji Apache, więc postanowiłem jako osobisty projekt dowiedzieć się, jak
mod_rewrite
naprawdę działa i współdziała z resztą Apache rdzeń, więc w ciągu ostatnich kilku miesięcy instrumentowałem przypadki testowe za pomocąstrace
+ wiercenia w kodzie źródłowym, aby uzyskać kontrolę nad tym wszystkim.Oto kilka kluczowych uwag, które twórcy reguł powinni przepisać na nowo:
.htaccess
przetwarzania PerDir ( ).Chciałbym powiedzieć, że z tego powodu prawie trzeba podzielić społeczności użytkowników na przepisywanie na dwie kategorie i traktować je jako całkowicie odrębne:
Osoby z dostępem root do konfiguracji Apache . Zazwyczaj są to admin / developer z serwerem / maszyną wirtualną dedykowaną do aplikacji, a komunikat tutaj jest dość prosty: unikaj używania
.htaccess
plików, jeśli to w ogóle możliwe; rób wszystko w konfiguracji serwera lub vhosta. Debugowanie jest dość łatwe, ponieważ programista może ustawić debugowanie i ma dostęp do plików rewrite.log.Użytkownicy wspólnej usługi hostowanej (SHS) .
.htaccess
przetwarzania / Perdir, ponieważ nie ma innej alternatywy..htaccess
plik PerDir został wybrany i dlaczego. To nie wyjaśnia zawiłości cyklu PerDir i jak tego uniknąć.Istnieje prawdopodobnie trzecia społeczność: administracja i personel pomocniczy dostawców SHS, którzy kończą stopę w obu obozach i muszą ponieść konsekwencje powyższego.
Napisałem kilka postów na blogu w stylu artykułów (np. Więcej na temat używania reguł Rewrite w plikach .htaccess ), które obejmują wiele szczegółowych kwestii, których nie powtórzę tutaj, aby ten artykuł był krótki. Mam swoją wspólną usługę, a także wspieram niektóre projekty dedykowane i VM FLOSS. Zacząłem od używania standardowej maszyny Wirtualnej LAMP jako pojazdu testowego dla mojego konta SHS, ale w końcu lepiej było zrobić odpowiednią lustrzaną Maszynę Wirtualną (opisaną tutaj ).
Jednak pod względem sposobu, w jaki społeczność administracyjna powinna wspierać
.htaccess
użytkowników, uważam, że musimy się rozwijać i oferować:.htaccess
reguł przepisywaniaWskazówki, jak uzyskać wbudowaną diagnostykę na podstawie reguł (np
[E=VAR:EXPR]
z faktu, żeEXPR
rozszerzysz odwołania wsteczne ($ N lub% N), aby udostępnić je jako diagnostykę dla skryptu docelowego.Jeśli zamawiasz miejscowo reguły przepisywania przy użyciu flag [OR], [C], [SKIP] i [L], aby cały schemat przepisywania działał bez potrzeby wykorzystywania przekierowania wewnętrznego, możesz dodać następujące reguły jako regułę 1, aby uniknąć wszystkie problemy z zapętleniem:
źródło
.htaccess
tematy, a zobaczysz. Większość początkujących jest beznadziejnie zdezorientowana - większość z nich ma pierwsze doświadczenie z usługą LAMP i mod_rewrite w usłudze współdzielonej, a zatem nie ma dostępu root do konfiguracji system / vhost i musi korzystać z przetwarzania.htaccess
plików przez katalog . Istnieją ważne różnice, które początkujący musi „wykrwawić”. Uważałbym się za użytkownika zaawansowanego i wciąż odkrywam subtelności. Jak mówię, musiałem użyć skanowania strace i kodu źródłowego, aby wypracować pewne aspekty. Nie byłoby to konieczne. :-(.htaccess
, co jest strasznie kruche, skomplikowane i mylące, nawet dla ekspertów. Wciąż mam problemy.Korzystanie z rewritemap
Istnieje wiele rzeczy, które możesz zrobić dzięki przepisywaniu map. Rewritemaps są deklarowane przy użyciu dyrektywy Rewritemap, a następnie mogą być używane zarówno w ocenach RewritCond, jak i w RewriteRule Subsitutions.
Ogólna składnia RewriteMap to:
Na przykład:
Następnie możesz użyć nazwy mapy do konstrukcji takich jak ta:
Mapa zawiera pary klucz / wartość. Jeśli klucz zostanie znaleziony, wartość jest zastępowana. Proste mapy są zwykłymi plikami tekstowymi, ale możesz używać map skrótów, a nawet zapytań SQL. Więcej szczegółów znajduje się w dokumentach:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap
Ciągi nieodkształcające.
Istnieją cztery wewnętrzne mapy, których możesz użyć do wykonania pewnych operacji. Przydadzą się zwłaszcza struny nieskalujące.
Na przykład: chcę przetestować ciąg „cafe” w ciągu zapytania. Jednak przeglądarka uniknie tego przed wysłaniem go na mój serwer, więc będę musiał dowiedzieć się, jaka jest wersja zmiany adresu URL dla każdego ciągu, który chcę dopasować, lub mogę po prostu cofnąć widok ...
Zwróć uwagę, jak korzystam z jednego RewriteCond, aby przechwycić argument argumentu parametru ciągu zapytania, a następnie użyć mapy w drugim rewriteCond, aby go cofnąć. Następnie porównuje się. Zwróć też uwagę, jak potrzebuję nam% 2 jako klucza w mapie ponownego zapisu, ponieważ% 1 będzie zawierał „lokalizację” lub „miejsce”. Gdy użyjesz nawiasów do grupowania wzorów, zostaną one również przechwycone, niezależnie od tego, czy planujesz użyć wyniku przechwytywania, czy nie ...
źródło
mod_rewrite
wyrażeń regularnych obsługuje grupy nie przechwytujące, takie jak(?:location|place)
i to będzie miało tylko jedno przechwytywanie w przykładzie.Bardzo łatwym problemem jest przepisywanie adresów URL, które zmieniają widoczną ścieżkę, np. Z
/base/1234/index.html
na/base/script.php?id=1234
. Klient nie znajdzie żadnych obrazów ani CSS ze względnymi ścieżkami do lokalizacji skryptu. Wiele opcji rozwiązania tego problemu można znaleźć na tej stronie .źródło
<base>
tagu jest najłatwiejsze do naśladowania i nadal umożliwia względne ścieżki.