Przekieruj, zmieniaj adresy URL lub przekierowuj HTTP na HTTPS w Apache - wszystko, co chciałeś wiedzieć o regułach Mod_Rewrite, ale bałeś się zapytać

264

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.

Kyle Brandt
źródło
9
Ideą tego pytania jest przybliżenie wszystkich niekończących się pytań mod_rewrite, które doprowadzają naszych zwykłych użytkowników do szaleństwa. Jest to bardzo podobne do tego, co zostało zrobione z podsieciami na serverfault.com/questions/49765/how-does-subnetting-work .
Kyle Brandt,
1
Poza tym tak naprawdę nie chcę zbyt wielu pozytywnych opinii na to pytanie , raczej powinni przejść do odpowiedzi. Nie chcę tego CW, ponieważ chcę się upewnić, że plakat uzyska pełne uznanie za to, co mam nadzieję, że odpowiedź mod_rewrite zakończy wszystkie pytania mod_rewrite .
Kyle Brandt,
4
Przepraszam, głosowałem za pytaniem. ;-) Naprawdę myślę, że musi pojawić się na górze (lub w pobliżu) mod-rewritewyszukiwania tagów / filtrów.
Steven poniedziałek,
Ktoś inny (tm) powinien obsługiwać typowe przypadki użycia. Nie znam ich wystarczająco dobrze, aby zrobić to sprawiedliwie.
sysadmin1138
Być może to pytanie powinno zostać połączone z tagiem mod-rewrite wiki, aby ścieżka była jeszcze krótsza.
beldaz

Odpowiedzi:

224

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 Onnależy podać dyrektywę, ponieważ włącza to przetwarzanie mod_rewrite. Powinno to nastąpić przed innymi dyrektywami przepisującymi.

RewriteCondpoprzedzanie RewriteRulepowoduje, że JEDNA reguła podlega warunkom. Wszelkie poniższe RewriteRules będą przetwarzane tak, jakby nie podlegały warunkom.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html

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:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html        $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg         $/blog/$1.sf.jpg

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:

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

Ale prawdopodobnie należy to zrobić przy użyciu nieco trudniejszej składni zastępczej.

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Bardziej złożona RewriteRule zawiera warunki do przetwarzania. Ostatni w nawiasach (html|jpg)mówi RewriteRule, aby pasował do jednego htmllub jpg, 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):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)    [OR]
RewriteCond %{HTTP_REFERER}                ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

Aby obsługiwać strony, o których mowa w ServerFault, w przeglądarkach Chrome (domyślnie AND):

RewriteEngine On
RewriteCond %{HTTP_REFERER}                ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT}             ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg)        /blog/$1.sf.$2

RewriteBasejest również specyficzny dla zamówienia, ponieważ określa, w jaki sposób następujące RewriteRuledyrektywy 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:

RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

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 RewriteRuleuważ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:

RewriteEngine On

##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER}                                   ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg)     $1.sf.$2

##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER}           ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg)         $1.sf.$2

Jak widać, RewriteBasepozwala 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ą.

RewriteRule ^/blog/(.*)$    /newblog/$1

.*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 $.

RewriteRule ^/blog/.*/(.*)$  /newblog/$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).

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$2

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.

RewriteRule ^/blog/(2008|2009)/(.*)$   /newblog/$1/$2

W tym przypadku używamy 1 $ w przepisanym ciągu.

RewriteRule ^/blog/(20[0-9][0-9])/(.*)$   /newblog/$1/$2

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.

RewriteRule ^/blog/(20[0-9]{2})/(.*)$  /newblog/$1/$2

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).

RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html   /newblog/$1/$2.shtml

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.

RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html  /newblog/$1/$2.shtml

Przechwytuje nazwy plików z myślnikami. Ponieważ jednak -jest znakiem specjalnym w wyrażeniach w nawiasach, musi być pierwszym znakiem w wyrażeniu.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

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 .

RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html  /newblog/$1/$2.shtml  [L]

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. Pozwalajpgaby 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 AddTypedyrektywy.

Wiesz, jak powiedziałem, że RewriteConddotyczy jednej i tylko jednej reguły? Możesz to obejść, łącząc łańcuchy.

RewriteEngine On
RewriteCond %{HTTP_REFERER}          ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html        /blog/$1.sf.html     [C]
RewriteRule ^/blog/(.*)\.jpg         /blog/$1.sf.jpg

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.

RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html   /newblog/$1/$2.shtml

Można to uprościć za pomocą flag:

RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html   /newblog/$1/$2.shtml   [NC]

Ponadto niektóre flagi dotyczą również RewriteCond. W szczególności NoCase.

RewriteCond %{HTTP_REFERER}        ^https?://serverfault\.com(/|$)     [NC]

Dopasuje „ServerFault.com”

sysadmin1138
źródło
9
Dobra robota. [wypełniający]
EEAA,
3
Bardzo ładny mod_rewritei regularny podkład. +1.
Steven poniedziałek,
3
Jest to czasami warto wiedzieć, że RewriteCondjest 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…”
Dennis Williamson,
2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1nie 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.
adapttr
1
@ sysadmin1138, myślę, że ta odpowiedź jest dobra, ale może być lepiej, jeśli opracować bardziej na flagach E, N, NS, P, PT, a S z przykładów, ponieważ te flagi nie jest oczywiste, w jaki sposób one działają itp
Pacerier
39

Jaki jest podstawowy format i struktura reguł mod_rewrite?

Odłożę się do doskonałej odpowiedzi sysadmin1138 na te kwestie.

Jakiej formy / smaku wyrażeń regularnych potrzebuję, aby dobrze zrozumieć?

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.

Jakie są najczęstsze błędy / pułapki podczas pisania reguł przepisywania?

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:

  • 500 - Wewnętrzny błąd serwera - Usuń kontrolki karetki Windows w plikach konfiguracyjnych, jeśli są obecne, upewnij się, że mod_rewrite jest włączony (zawijaj dyrektywy IfModulewarunkowo, aby uniknąć tego scenariusza), sprawdź składnię dyrektywy, komentuj dyrektywy aż do zidentyfikowania problemu
  • Pętla przekierowań - skorzystaj z RewriteLog i RewriteLogLevel, komentuj dyrektywy aż do zidentyfikowania problemu

Jaka jest dobra metoda testowania i weryfikacji reguł mod_rewrite?

Najpierw 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:

<?php
  var_dump($_SERVER);
?>

... 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 RewriteLogdyrektywy mod_rewrite, aby zarejestrować działanie w pliku i ustawićRewriteLogLevel 3

Czy są jakieś konsekwencje SEO lub wydajności reguł mod_rewrite, o których powinienem wiedzieć?

AllowOverride allwpływa na wydajność serwera, ponieważ Apache musi sprawdzać .htaccesspliki i analizować dyrektywy przy każdym żądaniu - jeśli to możliwe, zachowaj wszystkie dyrektywy w konfiguracji VirtualHost dla swojej witryny lub włącz .htaccessprzesł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.

Czy zdarzają się często sytuacje, w których mod_rewrite może wydawać się odpowiednim narzędziem do pracy, ale tak nie jest?

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.

Jakie są najczęstsze przykłady?

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).

danlefree
źródło
Dzięki za link AskApache. Właśnie tego szukałem!
sica07,
Klaun AskApache nie jest oficjalnie obsługiwany przez ASF. Wiele z tego, co mówi, jest dyskusyjne lub po prostu błędne.
adapttr
@adaptr Podziel się najlepszymi zasobami, o których najwyraźniej jesteś świadomy.
danlefree
„typowe sytuacje, w których mod_rewrite może wydawać się odpowiednim narzędziem do pracy, ale nie jest?” - proste przekierowania, w których mod_rewrite nie jest już używany. Użyj mod_alias Redirectlub RedirectMatchzamiast. Zobacz także dokumenty Apache: Kiedy nie używać mod_rewrite
MrWhite
21

Jak 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_rewritenaprawdę 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:

  • Niektóre aspekty przepisywanie są wspólne dla konfiguracji serwera, wirtualnego hosta, katalog, .htaccess przetwarzania jednak
  • Niektóre przetwarzanie jest bardzo różne dla konfiguracji root (konfiguracja serwera, host wirtualny i katalog) w przeciwieństwie do .htaccessprzetwarzania PerDir ( ).
  • Co gorsza, ponieważ przetwarzanie PerDir może prawie bezkrytycznie wyzwalać cykliczne WYKONYWANIE WEWNĘTRZNE, elementy konfiguracji root muszą być zapisane ze świadomością, że takie przetwarzanie PerDir może to spowodować.

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 .htaccessplikó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) .

    • Tacy użytkownicy muszą korzystać z .htaccessprzetwarzania / Perdir, ponieważ nie ma innej alternatywy.
    • Co gorsza, poziom umiejętności takich użytkowników (jeśli chodzi o wykorzystanie logiki logicznej mod_rewrite opartej na wyrażeniach regularnych) jest ogólnie znacznie niższy niż doświadczonych administratorów.
    • Apache i dostawcy hostingu nie oferują wsparcia w zakresie debugowania / diagnostyki. Jedyną informacją diagnostyczną jest udane przekierowanie, przekierowanie do niewłaściwego identyfikatora URI. lub kod stanu 404/500. To sprawia, że ​​są zdezorientowani i bezradni.
    • Apache jest bardzo słaby, tłumacząc, jak działa przepisywanie w tym przypadku użycia. Na przykład nie zawiera jasnego wyjaśnienia, który .htaccessplik 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ć .htaccessużytkowników, uważam, że musimy się rozwijać i oferować:

  • Spójny opis działania systemu przepisywania w przetwarzaniu PerDir
  • Zestaw wytycznych / najlepszych praktyk dotyczących pisania .htaccessreguł przepisywania
  • Prosty internetowy analizator skryptów przepisujących podobny do parserów HTML W3C, ale za pomocą którego użytkownicy mogą wprowadzać testowe identyfikatory URI lub testować wektory tego samego i uzyskiwać natychmiastowy zapis przepływu logiki przepisywania /
  • Wskazówki, jak uzyskać wbudowaną diagnostykę na podstawie reguł (np

    • Skorzystaj [E=VAR:EXPR]z faktu, że EXPRrozszerzysz 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:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      
TerryE
źródło
Jest to dobrze udokumentowane. Dlaczego według ciebie dokumentacja tego nie wyjaśnia?
adapttr
2
Wszystko, co musisz zrobić, to zasubskrybować .htaccesstematy, 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 .htaccessplikó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. :-(
TerryE
W pełni się zgadzam. „Musimy podzielić społeczności użytkowników na przepisywanie na dwie kategorie i traktować je jako całkowicie odrębne”. Niektórzy użytkownicy korzystają z hostingu współdzielonego i muszą na nim polegać .htaccess, co jest strasznie kruche, skomplikowane i mylące, nawet dla ekspertów. Wciąż mam problemy.
Ryan,
15

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:

RewriteMap MapName MapType:MapSource

Na przykład:

RewriteMap examplemap txt:/path/to/file/map.txt

Następnie możesz użyć nazwy mapy do konstrukcji takich jak ta:

${examplemap:key}

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 ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

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 ...

Krist van Besien
źródło
Ostatnie zdanie nie jest do końca prawdą. Mechanizm mod_rewritewyrażeń regularnych obsługuje grupy nie przechwytujące, takie jak (?:location|place)i to będzie miało tylko jedno przechwytywanie w przykładzie.
TerryE
12

Jakie są najczęstsze błędy / pułapki podczas pisania reguł przepisywania?

Bardzo łatwym problemem jest przepisywanie adresów URL, które zmieniają widoczną ścieżkę, np. Z /base/1234/index.htmlna /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 .

Beldaz
źródło
1
Dzięki za link. Szczególnie podczas pracy z innymi członkami zespołu, którzy nie są zaznajomieni z przepisywaniem, uważam, że dodanie <base>tagu jest najłatwiejsze do naśladowania i nadal umożliwia względne ścieżki.
kontur