Ordre syntaxique du mod_rewrite
mod_rewrite a des règles d'ordonnancement spécifiques qui affectent le traitement. Avant que tout ne soit fait, le RewriteEngine On
doit être donnée car elle active le traitement du mod_rewrite. Elle doit être placée avant toute autre directive de réécriture.
RewriteCond
précédant RewriteRule
rend cette règle unique soumise au conditionnel. Toutes les RewriteRules suivantes seront traitées comme si elles n'étaient pas soumises aux conditionnels.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
Dans ce cas simple, si le référent HTTP est serverfault.com, redirigez les requêtes du blog vers des pages spéciales serverfault (nous sommes si spéciaux). Toutefois, si le bloc ci-dessus comportait une ligne RewriteRule supplémentaire :
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg $/blog/$1.sf.jpg
Tous les fichiers .jpg iraient sur les pages spéciales de défaut de serveur, et pas seulement ceux dont le référent indique qu'ils viennent d'ici. Ce n'est clairement pas l'intention de la façon dont ces règles sont écrites. Cela pourrait être fait avec plusieurs règles 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
Mais cela devrait probablement être fait avec une syntaxe de remplacement plus délicate.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
La RewriteRule, plus complexe, contient les conditionnels à traiter. La dernière parenthèse, (html|jpg)
indique à RewriteRule de correspondre à l'un ou l'autre des éléments suivants html
o jpg
et de représenter la chaîne correspondante comme étant $2 dans la chaîne réécrite. Ce bloc est logiquement identique au précédent, avec deux paires RewriteCond/RewriteRule, il le fait simplement sur deux lignes au lieu de quatre.
Les lignes RewriteCond multiples sont implicitement ANDées, et peuvent être explicitement ORées. Pour gérer les référents à la fois de ServerFault et de Super User (OR explicite) :
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [OR]
RewriteCond %{HTTP_REFERER} ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
Pour servir les pages référencées ServerFault avec les navigateurs Chrome (ET implicite) :
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteBase
est également spécifique à l'ordre puisqu'il précise comment RewriteRule
se chargent de leur traitement. Elle est très utile dans les fichiers .htaccess. Si vous l'utilisez, elle doit être la première directive sous "RewriteEngine on" dans un fichier .htaccess. Prenons cet exemple :
RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Cela indique au mod_rewrite que l'URL qu'il traite actuellement est arrivée par le biais de http://example.com/blog/ au lieu du chemin du répertoire physique (/home/$Username/public_html/blog) et de le traiter en conséquence. Pour cette raison, la méthode RewriteRule
considère que le début de la chaîne doit se trouver après le "/blog" de l'URL. Voici la même chose écrite de deux manières différentes. L'une avec RewriteBase, l'autre sans :
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
Comme vous pouvez le voir, RewriteBase
permet aux règles de réécriture de s'appuyer sur le web- site chemin vers le contenu plutôt que le web- serveur ce qui peut les rendre plus intelligibles pour ceux qui éditent ces fichiers. De plus, ils peuvent rendre les directives plus courtes, ce qui présente un intérêt esthétique.
Syntaxe de la correspondance RewriteRule
RewriteRule a elle-même une syntaxe complexe pour faire correspondre les chaînes de caractères. Je couvrirai les drapeaux (des choses comme [PT]) dans une autre section. Parce que les administrateurs système apprennent par l'exemple plus souvent qu'en lisant un manuel de page de manuel Je vais donner des exemples et expliquer ce qu'ils font.
RewriteRule ^/blog/(.*)$ /newblog/$1
El .*
correspond à tout caractère unique ( .
) zéro ou plusieurs fois ( *
). En la mettant entre parenthèses, on lui demande de fournir la chaîne qui a été trouvée comme variable $1.
RewriteRule ^/blog/.*/(.*)$ /newblog/$1
Dans ce cas, le premier .* n'était PAS entouré de parens et n'est donc pas fourni à la chaîne réécrite. Cette règle supprime un niveau de répertoire sur le site du nouveau blog. (/blog/2009/échantillon.html devient /newblog/échantillon.html).
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$2
Dans ce cas, la première expression entre parenthèses crée un groupe de correspondance. Celui-ci devient $1, qui n'est pas nécessaire et n'est donc pas utilisé dans la chaîne réécrite.
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$1/$2
Dans ce cas, nous utilisons $1 dans la chaîne réécrite.
RewriteRule ^/blog/(20[0-9][0-9])/(.*)$ /newblog/$1/$2
Cette règle utilise une syntaxe spéciale de parenthèses qui spécifie un caractère gamme . [0-9] correspond aux chiffres de 0 à 9. Cette règle spécifique traitera les années de 2000 à 2099.
RewriteRule ^/blog/(20[0-9]{2})/(.*)$ /newblog/$1/$2
Cette règle fait la même chose que la précédente, mais la partie {2} lui indique de faire correspondre le caractère précédent (une expression entre crochets dans ce cas) deux fois.
RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html /newblog/$1/$2.shtml
Cette casse correspondra à toute lettre minuscule de la deuxième expression correspondante, et ce pour autant de caractères que possible. Le site \.
indique que le point doit être traité comme un point réel, et non comme le caractère spécial qu'il est dans les exemples précédents. Cela ne fonctionnera pas si le nom du fichier contient des tirets.
RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html /newblog/$1/$2.shtml
Cela piège les noms de fichiers contenant des tirets. Cependant, comme -
est un caractère spécial dans les expressions entre crochets, il doit s'agir du caractère premièrement dans l'expression.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Cette version piège tout nom de fichier comportant des lettres, des chiffres ou le symbole -
dans le nom du fichier. C'est ainsi que vous spécifiez plusieurs jeux de caractères dans une expression entre crochets.
Règle de réécriture des drapeaux
Les drapeaux sur les règles de réécriture ont une multitude de significations et de cas d'utilisation particuliers. .
RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html /newblog/$1/$2.shtml [L]
Le drapeau est le [L]
à la fin de l'expression ci-dessus. Plusieurs drapeaux peuvent être utilisés, séparés par une virgule. La documentation liée décrit chacun d'eux, mais les voici quand même :
L \= Dernier. Arrêtez de traiter les RewriteRules une fois que celle-ci correspond. L'ordre compte !
C \= Chaîne. Continuez à traiter la RewriteRule suivante. Si cette règle ne correspond pas, alors la règle suivante ne sera pas exécutée. Nous y reviendrons plus tard.
E \= Définir une variable environnementale. Apache dispose de plusieurs variables environnementales qui peuvent affecter le comportement du serveur web.
F \= Interdit. Renvoie une erreur 403-Forbidden si cette règle correspond.
G \= Gone. Renvoie une erreur 410-Gone si cette règle correspond.
H \= Handler. Force la demande à être traitée comme s'il s'agissait du type MIME spécifié.
N \= Suivant. Force la règle à recommencer et à se recoupler. ATTENTION ! Des boucles peuvent en résulter.
NC \= Pas de cas. Autorise jpg
pour correspondre à la fois à jpg et à JPG.
NE \= Pas d'échappement. Empêche la réécriture des caractères spéciaux (. ? # & etc) dans leurs équivalents en code hexadécimal.
NS \= Pas de sous-requêtes. Si vous utilisez des inclusions côté serveur, cela empêchera les correspondances avec les fichiers inclus.
P \= Proxy. Force la règle à être traitée par mod_proxy. Fournir de manière transparente du contenu provenant d'autres serveurs, car votre serveur web le récupère et le remet à disposition. C'est un drapeau dangereux, car s'il est mal écrit, votre serveur web deviendra un proxy ouvert, ce qui est mauvais.
PT \= Pass Through. Prendre en compte les déclarations Alias dans la correspondance RewriteRule.
QSA \= QSAppend. Lorsque la chaîne originale contient une requête ( http://example.com/thing?asp=foo ) ajoute la chaîne de requête originale à la chaîne réécrite. Normalement, elle devrait être rejetée. Important pour le contenu dynamique.
R \= Redirection. Fournit une redirection HTTP vers l'URL spécifiée. Peut également fournir le code de redirection exact [R=303]. Très similaire à RedirectMatch
qui est plus rapide et devrait être utilisé lorsque cela est possible.
S \= Sauter. Ignorer cette règle.
T \= Type. Spécifiez le type de fichier mime du contenu renvoyé. Très similaire à l'option AddType
directive.
Tu sais que j'ai dit que RewriteCond
s'applique à une et une seule règle ? Eh bien, vous pouvez contourner cela en enchaînant.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html [C]
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Comme la première RewriteRule possède l'indicateur Chain, la seconde règle de réécriture s'exécutera lorsque la première le fera, c'est-à-dire lorsque la règle RewriteCond précédente sera satisfaite. Pratique si les expressions régulières d'Apache vous font mal au cerveau. Cependant, la méthode tout-en-un que j'ai indiquée dans la première section est plus rapide du point de vue de l'optimisation.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Cela peut être simplifié grâce à des drapeaux :
RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html /newblog/$1/$2.shtml [NC]
De plus, certains drapeaux s'appliquent également à RewriteCond. Notamment, NoCase.
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [NC]
Correspond à "ServerFault.com"
9 votes
L'idée derrière cette question est de donner un chemin proche pour toutes les questions interminables sur mod_rewrite qui rendent fous nos utilisateurs les plus réguliers. C'est très similaire à ce qui a été fait avec le subnetting chez serverfault.com/questions/49765/how-does-subnetting-work .
1 votes
Aussi, je ne veux pas vraiment avoir trop de votes positifs sur ce sujet. question mais ils doivent plutôt aller chercher la réponse. Je ne veux pas faire de CW parce que je veux m'assurer que l'affiche est pleinement créditée de ce que j'espère être la meilleure réponse. la réponse à toutes les questions sur le mod_rewrite .
4 votes
Désolé, j'ai upvoted la question ;-) Je pense vraiment qu'elle doit apparaître en haut (ou à proximité) de la page d'accueil de
mod-rewrite
recherches/filtres de tags.0 votes
Quelqu'un d'autre (tm) devrait s'occuper des cas d'utilisation courants. Je ne les connais pas assez bien pour leur rendre justice.
0 votes
Peut-être que cette question devrait être liée au wiki des tags mod-rewrite pour rendre le chemin encore plus court.
0 votes
C'est génial. Je l'ai mis dans le wiki mod_rewrite tag sur Stack Overflow.
0 votes
Aussi, discussion connexe : meta.stackexchange.com/questions/73742/