C'est une question canonique sur le mod_rewrite d'Apache.
La modification d'une URL de demande ou la redirection d'utilisateurs vers une URL différente de celle demandée à l'origine est effectuée à l'aide de mod_rewrite. Cela inclut des choses telles que:
- Changer HTTP en HTTPS (ou l'inverse)
- Modification d'une demande pour une page qui n'existe plus pour un nouveau remplacement.
- Modification d'un format d'URL (tel que? Id = 3433 en / id / 3433)
- Présenter une page différente basée sur le navigateur, basée sur le référant, basée sur tout ce qui est possible sous la lune et le soleil.
- Tout ce que vous voulez déranger avec une URL
Tout ce que vous avez toujours voulu savoir sur les règles Mod_Rewrite sans oser le demander!
Comment puis-je devenir un expert en écriture de règles mod_rewrite?
- Quels sont le format et la structure fondamentaux des règles mod_rewrite?
- De quelle forme / saveur d'expressions régulières ai-je besoin pour bien comprendre?
- Quelles sont les erreurs / écueils les plus courants lors de l’écriture des règles de réécriture?
- Quelle est la bonne méthode pour tester et vérifier les règles mod_rewrite?
- Existe-t-il des implications des règles mod_rewrite sur le référencement ou la performance dont je devrais être au courant?
- Existe-t-il des situations courantes dans lesquelles mod_rewrite peut sembler être le bon outil pour le travail mais ne l'est pas?
- Quels sont quelques exemples courants?
Un endroit pour tester vos règles
Le site Web testeur htaccess est un endroit idéal pour jouer avec vos règles et les tester. Il affiche même la sortie de débogage afin que vous puissiez voir ce qui correspond ou non.
apache-2.2
mod-rewrite
redirect
redirection
301-redirect
Kyle Brandt
la source
la source
mod-rewrite
recherches / filtres de balises.Réponses:
ordre de syntaxe mod_rewrite
mod_rewrite a des règles de classement spécifiques qui affectent le traitement. Avant que quoi que ce soit ne soit fait, la
RewriteEngine On
directive doit être donnée car cela active le traitement mod_rewrite. Cela devrait être avant toute autre directive de réécriture.RewriteCond
ce qui précèdeRewriteRule
rend cette règle soumise au conditionnel. Toutes les RewriteRules suivantes seront traitées comme si elles n'étaient pas soumises à des conditions.Dans ce cas simple, si le référent HTTP provient de serverfault.com, redirigez les demandes de blogs vers des pages spéciales serverfault (nous sommes tout simplement spéciaux). Toutefois, si le bloc ci-dessus comportait une ligne RewriteRule supplémentaire:
Tous les fichiers .jpg iraient aux pages spéciales serverfault, pas seulement à celles avec un référent indiquant qu'il venait 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:
Mais devrait probablement être fait avec une syntaxe de remplacement plus délicate.
Le plus complexe RewriteRule contient les conditions pour le traitement. La dernière parenthétique
(html|jpg)
indique à RewriteRule de correspondre pourhtml
oujpg
, et de représenter la chaîne correspondante sous forme de $ 2 dans la chaîne réécrite. Ceci est logiquement identique au bloc précédent, avec deux paires RewriteCond / RewriteRule, il le fait simplement sur deux lignes au lieu de quatre.Plusieurs lignes RewriteCond sont implicitement AND, et peuvent être explicitement OR. Pour gérer les référents de ServerFault et de super utilisateur (OU explicite):
Pour servir les pages référencées ServerFault avec les navigateurs Chrome (ET implicite):
RewriteBase
est également spécifique à la commande car elle spécifie comment lesRewriteRule
directives suivantes gèrent leur traitement. C'est très utile dans les fichiers .htaccess. Si utilisé, il devrait s'agir de la première directive sous "RewriteEngine on" dans un fichier .htaccess. Prenons cet exemple:Ceci indique à mod_rewrite que cette URL particulière en cours de traitement a été arrivée via http://example.com/blog/ au lieu du chemin du répertoire physique (/ home / $ Nom d'utilisateur / public_html / blog) et de le traiter en conséquence. Pour cette raison,
RewriteRule
il considère que le début de chaîne se situe après le "/ blog" dans l'URL. Voici la même chose écrite de deux manières différentes. Une avec RewriteBase, l'autre sans:Comme vous pouvez le constater, les
RewriteBase
règles de réécriture exploitent le chemin d'accès du site Web au contenu plutôt que le serveur Web , ce qui peut les rendre plus intelligibles pour ceux qui modifient de tels fichiers. En outre, ils peuvent raccourcir les directives, ce qui présente un attrait esthétique.Syntaxe de correspondance RewriteRule
RewriteRule a lui-même une syntaxe complexe pour faire correspondre les chaînes. Je couvrirai les drapeaux (des choses comme [PT]) dans une autre section. Comme les administrateurs système apprennent par l'exemple plus souvent que par la lecture d'une page de manuel, je vais donner des exemples et expliquer ce qu'ils font.
La
.*
construction correspond à tout caractère unique (.
) zéro ou plusieurs fois (*
). Le mettre entre parenthèses lui indique de fournir la chaîne qui correspondait à la variable $ 1.Dans ce cas, le premier. * N'était PAS compris entre parenthèses et n'est donc pas fourni à la chaîne réécrite. Cette règle supprime un niveau de répertoire sur le nouveau site de blog. (/blog/2009/sample.html devient /newblog/sample.html).
Dans ce cas, la première expression entre parenthèses définit un groupe correspondant. Cela devient $ 1, ce qui n'est pas nécessaire et n'est donc pas utilisé dans la chaîne réécrite.
Dans ce cas, nous utilisons $ 1 dans la chaîne réécrite.
Cette règle utilise une syntaxe de crochet spéciale qui spécifie une plage de caractères . [0-9] correspond aux chiffres 0 à 9. Cette règle spécifique s’applique aux années 2000 à 2099.
Cela fait la même chose que la règle précédente, mais la partie {2} lui dit de faire correspondre le caractère précédent (une expression entre crochets dans ce cas) deux fois.
Cette casse correspondra à n'importe quelle lettre minuscule de la deuxième expression correspondante et le fera pour autant de caractères que possible. La
\.
construction lui dit de traiter la période comme une période réelle, et non comme le caractère spécial qu'il est dans les exemples précédents. Cela se brisera si le nom du fichier contient des tirets.Cela intercepte les noms de fichiers contenant des tirets. Cependant, comme il
-
s'agit d'un caractère spécial dans les expressions entre crochets, il doit s'agir du premier caractère de l'expression.Cette version intercepte tout nom de fichier avec des lettres, des chiffres ou le
-
caractère dans le nom du fichier. Voici comment spécifier plusieurs jeux de caractères dans une expression entre crochets.Drapeaux RewriteRule
Les drapeaux sur les règles de réécriture ont une foule de significations et de cas d'utilisation spéciaux .
Le drapeau est
[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, mais les voici quand même:L = dernier. Arrêtez le traitement de RewriteRules une fois que celui-ci correspond. L'ordre compte!
C = chaîne. Continuer le traitement de la prochaine RewriteRule. Si cette règle ne correspond pas, la règle suivante ne sera pas exécutée. Plus sur cela plus tard.
E = Définir la variable environnementale. Apache a diverses variables d'environnement qui peuvent affecter le comportement du serveur Web.
F = Interdit. Retourne une erreur 403-Forbidden si cette règle correspond.
G = parti. Retourne une erreur 410-Gone si cette règle correspond.
H = gestionnaire. Force la demande à être traitée comme s'il s'agissait du type MIME spécifié.
N = Suivant. Force la règle à recommencer et à correspondre à nouveau. FAITES ATTENTION! Des boucles peuvent en résulter.
NC = Aucun cas. Permet
jpg
pour correspondre à la fois jpg et JPG.NE = pas d'échappatoire. Empêche la réécriture des caractères spéciaux (.? # & Etc) en leurs équivalents de code hexadécimal.
NS = Pas de sous-demandes. Si vous utilisez des inclusions côté serveur, cela empêchera les correspondances avec les fichiers inclus.
P = Proxy. Force la règle à être manipulée par mod_proxy. Fournissez le contenu de manière transparente à partir d'autres serveurs, car votre serveur Web le récupère et le restaure. C’est un drapeau dangereux, puisqu’un texte mal écrit transformera votre serveur Web en proxy ouvert et c’est mauvais.
PT = Pass Through. Prendre en compte les instructions Alias dans la correspondance RewriteRule.
QSA = QSAppend. Lorsque la chaîne d'origine contient une requête ( http://example.com/thing?asp=foo) ajoute la chaîne de requête originale à la chaîne réécrite. Normalement, il serait jeté. Important pour le contenu dynamique.
R = redirection. Fournissez une redirection HTTP vers l'URL spécifiée. Peut également fournir le code de redirection exact [R = 303]. Très semblable à
RedirectMatch
, ce qui est plus rapide et devrait être utilisé lorsque cela est possible.S = Passer. Passer cette règle.
T = Type. Spécifiez le type mime du contenu renvoyé. Très semblable à la
AddType
directive.Vous savez comment j'ai dit que cela
RewriteCond
s'applique à une et une seule règle? Eh bien, vous pouvez contourner cela en chaînant.Comme la première règle RewriteRule a l'indicateur Chain, la deuxième règle rewrite s'exécutera lorsque la première le sera, ce qui correspond à la correspondance de la règle précédente RewriteCond. Très pratique si les expressions régulières Apache vous font mal au cerveau. Cependant, la méthode tout-en-un-ligne que je pointe dans la première section est plus rapide du point de vue de l'optimisation.
Ceci peut être simplifié grâce aux drapeaux:
De plus, certains drapeaux s’appliquent également à RewriteCond. Notamment, NoCase.
Correspondra à "ServerFault.com"
la source
mod_rewrite
et amorce regex. +1RewriteCond
est effectivement traité après la mise enRewriteRule
correspondance. Vous voudrez peut-être dire "plus à ce sujet plus tard" près du sommet où vous dites "RewriteCond précédent à RewriteRule rend cette règle ONE soumise au conditionnel". Vous voudrez peut-être mentionner que les expressions rationnelles sont des expressions régulières compatibles Perl. Vous avez aussi une apostrophe étrangère dans "... la RewriteRule considère que c'est un début de chaîne ..."RewriteRule ^/blog/.*/(.*)$ /newblog/$1
ne correspond pas au premier composant du répertoire - les rewriterules sont gloutons par défaut. /.*/(.*) correspond à la fois à / 1 / (2) / et / 1/2/3/4/5 / (6) /, vous avez donc besoin de / [^ /] * / pour correspondre uniquement au chemin FIRST composant.Je vais me reporter à l'excellente réponse de sysadmin1138 sur ces points.
En plus de l'ordre de syntaxe, de correspondance de syntaxe / expressions régulières et des indicateurs RewriteRule décrits par sysadmin1138, je pense qu'il est important de mentionner que mod_rewrite expose les variables d'environnement Apache en fonction des en-têtes de requête HTTP et de la configuration d'Apache.
Je recommanderais mod_rewrite Debug Tutorial à AskApache pour une liste complète des variables pouvant être disponibles pour mod_rewrite.
La plupart des problèmes avec RewriteRule proviennent d'une incompréhension de la syntaxe PCRE / d'un échec pour échapper correctement à des caractères spéciaux ou d'un manque de compréhension du contenu de la ou des variables utilisées pour la correspondance.
Problèmes typiques et dépannage recommandé:
IfModule
conditionnelles pour éviter ce scénario), vérifiez la syntaxe des directives et commentez les directives jusqu'à ce que le problème soit identifié.Tout d’abord, examinez le contenu de la ou des variables d’environnement avec lesquelles vous prévoyez de faire correspondre le code. Si vous avez installé PHP, il vous suffit d’ajouter le bloc suivant à votre application:
... puis écrivez vos règles (de préférence pour les tests sur un serveur de développement) et notez toute correspondance ou activité incohérente dans votre fichier Apache ErrorLog .
Pour des règles plus complexes, utilisez la
RewriteLog
directive mod_rewrite pour consigner l'activité dans un fichier et définissezRewriteLogLevel 3
AllowOverride all
affecte les performances du serveur, car Apache doit rechercher les.htaccess
fichiers et analyser les directives à chaque requête. Conservez si possible toutes les directives dans la configuration de VirtualHost pour votre site ou n'activez les.htaccess
remplacements que pour les répertoires qui en ont besoin.Les directives pour les webmasters de Google stipulent explicitement: "Ne trompez pas vos utilisateurs et ne présentez pas aux moteurs de recherche un contenu différent de celui que vous affichez aux utilisateurs, ce qui est communément appelé" masquage "." - évitez de créer des directives mod_rewrite filtrant les robots des moteurs de recherche.
Les robots des moteurs de recherche préfèrent un contenu 1: 1: mappage d'URI (c'est la base du classement des liens vers le contenu) - si vous utilisez mod_rewrite pour créer des redirections temporaires ou si vous diffusez le même contenu sous plusieurs URI, envisagez de spécifier un URI canonique dans vos documents HTML.
C'est un sujet énorme (et potentiellement litigieux) en soi - mieux (à mon humble avis) pour traiter les utilisations au cas par cas et laisser les demandeurs déterminer si les solutions suggérées répondent à leurs besoins.
Les astuces et astuces mod_rewrite de AskApache couvrent pratiquement tous les cas d'utilisation courants qui apparaissent régulièrement. Cependant, la solution "correcte" pour un utilisateur donné peut dépendre de la sophistication de la configuration de l'utilisateur et des directives existantes (raison pour laquelle il s'agit généralement d'une solution simple). bonne idée de voir quelles autres directives un utilisateur a mises en place chaque fois qu'une question mod_rewrite est posée).
la source
Redirect
ou à laRedirectMatch
place. Voir aussi la documentation Apache: Quand ne pas utiliser mod_rewriteComme beaucoup d'administrateurs / développeurs, je lutte contre la complexité des règles de réécriture depuis des années et je suis mécontent de la documentation Apache existante. J'ai donc décidé, en tant que projet personnel, de faire la lumière sur la manière dont
mod_rewrite
fonctionne et interagit avec le reste d'Apache. Ainsi, au cours des derniers mois, j'ai instrumenté des scénarios de test avecstrace
+ une analyse approfondie du code source pour mieux comprendre tout cela.Voici quelques commentaires clés que les développeurs de règles de réécriture doivent prendre en compte:
.htaccess
traitement PerDir ( ).Je dirais aussi que, pour cette raison, il est presque nécessaire de diviser les communautés d'utilisateurs de réécriture en deux catégories et de les traiter de manière totalement distincte:
Ceux qui ont un accès root à la configuration Apache . Ce sont généralement des administrateurs / développeurs avec un serveur / une machine virtuelle dédiés à l’application, et le message est simple: évitez
.htaccess
autant que possible d’ utiliser des fichiers; faire tout dans votre serveur ou confhost config. Le débogage est assez facile car le développeur peut définir le débogage et a accès aux fichiers rewrite.log.Les utilisateurs d'un service hébergé partagé (SHS) .
.htaccess
traitement / Perdir car il n'y a pas d'alternative disponible..htaccess
fichier PerDir est sélectionné et pourquoi. Cela n'explique pas les subtilités du cyclisme PerDir et comment l'éviter.Il existe peut-être une troisième communauté: le personnel administratif et de soutien des fournisseurs SHS qui se retrouvent avec un pied dans les deux camps et doivent subir les conséquences de ce qui précède.
J'ai écrit quelques articles de blog de type article (par exemple, Plus d'informations sur l'utilisation des règles de réécriture dans les fichiers .htaccess ), qui couvrent un grand nombre de points détaillés que je ne vais pas répéter ici pour que ce message soit court. J'ai mon propre service partagé et je soutiens des projets dédiés et VM FLOSS. J'ai commencé par utiliser une machine virtuelle LAMP standard en tant que véhicule test pour mon compte SHS, mais j'ai finalement trouvé préférable de créer une machine virtuelle en miroir appropriée (décrite ici ).
Cependant, en ce qui concerne la manière dont la communauté administrative devrait aider les
.htaccess
utilisateurs, je pense que nous devons développer et proposer:.htaccess
règles de réécritureConseils pour obtenir des diagnostics intégrés à partir de vos règles (par exemple,
[E=VAR:EXPR]
le fait d’exploiter lesEXPR
références arrières ($ N ou% N) pour les rendre disponibles en tant que diagnostics pour le script cible.Si vous ordonnez topiquement vos règles de réécriture à l'aide des indicateurs [OR], [C], [SKIP] et [L] afin que l'ensemble du processus de réécriture fonctionne sans qu'il soit nécessaire d'exploiter la redirection interne, vous pouvez ajouter ce qui suit en tant que règle 1 pour éviter tous les tracas en boucle:
la source
.htaccess
sujets et vous verrez. La plupart des débutants sont désespérément confus - la plupart d'entre eux ont leur première expérience d'un service LAMP et de mod_rewrite sur un service partagé et n'ont donc pas d'accès root aux configurations system / vhost et doivent utiliser le traitement par.htaccess
répertoire à travers des fichiers. Il y a des différences importantes que le débutant doit "oublier". Je me considérerais comme un utilisateur puissant et je découvre encore des subtilités. Comme je le disais, j’ai dû utiliser le balayage strace et le code source pour résoudre certains aspects. Il n’était pas nécessaire. :-(.htaccess
, ce qui est terriblement fragile, compliqué et déroutant, même pour les experts. J'ai encore des problèmes.Utiliser rewritemap
Il y a beaucoup de choses que vous pouvez faire avec les cartes réécrites. Les rewritemaps sont déclarés à l'aide de la directive Rewritemap et peuvent ensuite être utilisés à la fois dans les évaluations RewritCond et dans les subventions RewriteRule.
La syntaxe générale pour RewriteMap est la suivante:
Par exemple:
Vous pouvez ensuite utiliser le nom de carte pour des constructions comme ceci:
La carte contient des paires clé / valeur. Si la clé est trouvée, la valeur est remplacée. Les cartes simples ne sont que des fichiers texte, mais vous pouvez utiliser des cartes de hachage et même des requêtes SQL. Plus de détails sont dans la documentation:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap
Des cordes sans faille.
Il existe quatre cartes internes que vous pouvez utiliser pour effectuer certaines manipulations. Les cordes particulièrement évasives peuvent être utiles.
Par exemple: je veux tester la chaîne "café" dans la chaîne de requête. Cependant, le navigateur échappera cela avant de l'envoyer à mon serveur. Je devrai donc déterminer quelle est la version échappée de l'URL pour chaque chaîne que je souhaite faire correspondre, ou je peux simplement la décompresser ...
Notez que j'utilise un RewriteCond pour capturer simplement l'argument dans le paramètre de chaîne de requête, puis que j'utilise la carte dans le deuxième rewriteCond pour le décompresser. Ceci est ensuite comparé. Notez également que j'ai besoin de% 2 en tant que clé du rewritemap, car% 1 contiendra "emplacement" ou "lieu". Lorsque vous utilisez des parenthèses pour regrouper des motifs, ceux-ci seront également capturés, que vous souhaitiez utiliser le résultat de la capture ou non ...
la source
mod_rewrite
moteur d'expression rationnelle prend en charge des groupes tels que ceux(?:location|place)
qui ne capturent pas et celui-ci n'aura qu'une capture dans l'exemple.Un écueil très facile consiste à réécrire les URL qui modifient le chemin apparent, par exemple de
/base/1234/index.html
à/base/script.php?id=1234
. Le client ne trouvera aucune image ni CSS ayant un chemin relatif vers l'emplacement du script. Un certain nombre d'options pour résoudre ce problème peuvent être trouvées dans cette FAQ .la source
<base>
balise est plus facile à suivre et permet néanmoins d'activer des chemins relatifs.