Il semble y avoir un nombre décent de mod_rewrite
threads ces derniers temps avec un peu de confusion sur la façon dont certains aspects fonctionnent. En conséquence, j'ai compilé quelques notes sur les fonctionnalités communes, et peut-être quelques nuances ennuyeuses.
Quelles autres fonctionnalités / problèmes courants avez-vous rencontrés en utilisant mod_rewrite
?
Réponses:
Où placer les règles mod_rewrite
mod_rewrite
les règles peuvent être placées dans lehttpd.conf
fichier ou dans le.htaccess
fichier. si vous y avez accèshttpd.conf
, placer des règles ici offrira un avantage en termes de performances (car les règles sont traitées une fois, par opposition à chaque fois que le.htaccess
fichier est appelé).Journalisation des requêtes mod_rewrite
La journalisation peut être activée à partir du
httpd.conf
fichier (y compris<Virtual Host>
):Cas d'utilisation courants
Pour canaliser toutes les demandes vers un seul point:
Depuis Apache 2.2.16, vous pouvez également utiliser
FallbackResource
.Gestion des redirections 301/302:
Remarque : les redirections externes sont implicitement 302 redirections:
Forcer SSL
Drapeaux communs:
[R]
ou[redirect]
- forcer une redirection (par défaut une redirection temporaire 302)[R=301]
ou[redirect=301]
- forcer une redirection permanente 301[L]
ou[last]
- arrêter le processus de réécriture (voir la note ci-dessous dans les pièges courants)[NC]
ou[nocase]
- spécifier que la correspondance doit être insensible à la casseL'utilisation de la forme longue des indicateurs est souvent plus lisible et aidera les autres qui viendront à lire votre code plus tard.
Vous pouvez séparer plusieurs indicateurs par une virgule:
Pièges courants
Mélanger les
mod_alias
redirections de style avecmod_rewrite
Remarque : vous pouvez mélanger
mod_alias
avecmod_rewrite
, mais cela implique plus de travail que la simple gestion des redirections de base comme ci-dessus.Le contexte affecte la syntaxe
Dans les
.htaccess
fichiers, une barre oblique de début n'est pas utilisée dans le modèle RewriteRule:[L] n'est pas le dernier! (quelquefois)
L'
[L]
indicateur arrête de traiter toutes les règles de réécriture supplémentaires pour ce passage dans l'ensemble de règles . Cependant, si l'URL a été modifiée lors de cette passe et que vous êtes dans le.htaccess
contexte ou la<Directory>
section, votre demande modifiée sera à nouveau renvoyée via le moteur d'analyse d'URL. Et au prochain passage, cela peut correspondre à une règle différente cette fois. Si vous ne comprenez pas cela, il semble souvent que votre[L]
drapeau n'a eu aucun effet.Notre journal de réécriture montre que les règles sont exécutées deux fois et que l'URL est mise à jour deux fois:
La meilleure façon de contourner cela est d'utiliser l'
[END]
indicateur ( voir la documentation Apache ) au lieu de l'[L]
indicateur, si vous voulez vraiment arrêter tout traitement ultérieur des règles (et les passes ultérieures). Cependant, l'[END]
indicateur n'est disponible que pour Apache v2.3.9 + , donc si vous avez v2.2 ou une version inférieure, vous êtes coincé avec seulement l'[L]
indicateur.Pour les versions antérieures, vous devez vous fier aux
RewriteCond
instructions pour empêcher la correspondance des règles lors des passages suivants du moteur d'analyse d'URL.Ou vous devez vous assurer que vos RewriteRule sont dans un contexte (c'est-à-dire
httpd.conf
) qui ne provoquera pas une nouvelle analyse de votre demande.la source
[L]
drapeau signifie qu'une règle est la dernière du traitement en cours, cela n'empêchera pas la réécriture, car ce sont des redirections internes, donc vousdirB
appliquez audirC
prochain traitement htaccess. SeulRewriteRule ^(.*)$ index.php?query=$1
sera une boucle infinie de redirections internes (en pratique, il se termine après 10 itérations). -1 parce que vous suggérez que [L] n'est pas le dernier . Ce n'est pas la fin du processus de réécriture, mais c'est le dernier .RewriteCond %{HTTPS} off
c'est le moyen préféré de vérifier une connexion HTTPS (dans votre exemple de forcer le trafic non SSL vers HTTPS)si vous avez besoin de `` bloquer '' les redirections / réécritures internes dans le .htaccess, jetez un œil à la
condition, comme discuté ici .
la source
.*
avec le[L]
drapeau , j'ai lu avant que je suis arrivé ici.200
,!=200
,^.
,^$
. Apparemment, la variable est définie sur200
pour une redirection, mais d'autres pages (erreurs et trucs) la définissent sur une certaine valeur. Maintenant , cela signifie que vous vérifiez soit siis empty
,is not empty
,is 200
ouis not 200
, en fonction de ce que vous avez besoin.L'accord avec RewriteBase:
Vous devez presque toujours définir RewriteBase. Si vous ne le faites pas, apache devine que votre base est le chemin du disque physique vers votre répertoire. Alors commencez par ceci:
la source
RewriteBase .
, ou quelque chose pour indiquer que l'URL doit rester la même, en changeant simplement ce que vous avez spécifié?RewriteBase
si vous utilisez la substitution de chemin relatif dans laRewriteRule
directive. Il vaut mieux éviter d'utiliser des chemins relatifs.RewriteBase
complètement car presque tous les développeurs comprennent mal ce qu'il fait. Comme @ w3d l'a dit, vous n'en avez besoin que si vous voulez enregistrer des caractères et que vous voulez appliquer la même base à toutes vos RewriteRules dans un seul fichier. Votre code sera probablement plus clair pour les autres si vous l'évitez.Autres pièges:
1- Parfois, c'est une bonne idée de désactiver les MultiViews
Je ne connais pas bien toutes les fonctionnalités de MultiViews, mais je sais que cela gâche mes règles mod_rewrite lorsqu'il est actif, car l'une de ses propriétés est d'essayer de `` deviner '' une extension d'un fichier qu'il pense que je recherche .
Je vais vous expliquer: Supposons que vous ayez 2 fichiers php dans votre répertoire web, file1.php et file2.php et que vous ajoutez ces conditions et règle à votre .htaccess:
Vous supposez que toutes les URL qui ne correspondent pas à un fichier ou à un répertoire seront récupérées par file1.php. Surprise! Cette règle n'est pas respectée pour l'url http: // myhost / file2 / somepath . Au lieu de cela, vous êtes pris dans file2.php.
Ce qui se passe, c'est que MultiViews a automatiquement deviné que l'URL que vous vouliez réellement était http: //myhost/file2.php/somepath et vous y a volontiers emmené.
Maintenant, vous n'avez aucune idée de ce qui vient de se passer et vous remettez en question tout ce que vous pensiez savoir sur mod_rewrite. Vous commencez alors à jouer avec les règles pour essayer de donner un sens à la logique derrière cette nouvelle situation, mais plus vous testez, moins cela a de sens.
Ok, en bref, si vous voulez que mod_rewrite fonctionne d'une manière qui se rapproche de la logique, désactiver MultiViews est un pas dans la bonne direction.
2- Activer FollowSymlinks
Celui-là, je ne connais pas vraiment les détails, mais je l'ai vu plusieurs fois mentionné, alors faites-le.
la source
+FollowSymLinks
est mentionné dans la documentation comme étant obligatoire pourmod_rewrite
travailler du tout, pour de vagues raisons de sécurité.L'équation peut être faite avec l'exemple suivant:
Équilibrage de charge dynamique:
Si vous utilisez le mod_proxy pour équilibrer votre système, il est possible d'ajouter une plage dynamique de serveur de travail.
la source
Une meilleure compréhension de l'indicateur [L] s'impose. Le drapeau [L] est le dernier, il vous suffit de comprendre ce qui provoquera le routage de votre requête via le moteur d'analyse d'URL. À partir de la documentation ( http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l ) (c'est moi qui souligne):
Ainsi , le [L] indicateur ne Arrêter le traitement des règles de réécriture supplémentaires pour ceux qui passent à travers l'ensemble de règles. Cependant, si votre règle marquée avec [L] a modifié la demande et que vous êtes dans le contexte .htaccess ou dans la
<Directory>
section, votre demande modifiée sera à nouveau renvoyée via le moteur d'analyse d'URL. Et au prochain passage, cela peut correspondre à une règle différente cette fois. Si vous ne comprenez pas ce qui s'est passé, il semble que votre première règle de réécriture avec l'indicateur [L] n'a eu aucun effet.La meilleure façon de contourner cela est d'utiliser l'indicateur [END] ( http://httpd.apache.org/docs/current/rewrite/flags.html#flag_end ) au lieu de l'indicateur [L], si vous voulez vraiment arrêter tout traitement ultérieur des règles (et analyse ultérieure). Cependant, l'indicateur [END] n'est disponible que pour Apache v2.3.9 +, donc si vous avez v2.2 ou une version antérieure, vous êtes coincé avec seulement l'indicateur [L]. Dans ce cas, vous devez vous fier aux instructions RewriteCond pour empêcher la mise en correspondance des règles lors des passages ultérieurs du moteur d'analyse d'URL. Ou vous devez vous assurer que vos RewriteRule sont dans un contexte (ie httpd.conf) qui ne provoquera pas une nouvelle analyse de votre requête.
la source
Les expansions de réécriture de la carte sont une autre fonctionnalité intéressante. Ils sont particulièrement utiles si vous avez une énorme quantité d'hôtes / réécritures à gérer:
Ils sont comme un remplacement de valeur-clé:
Ensuite, vous pouvez utiliser un mappage dans vos règles comme:
Vous trouverez plus d'informations sur ce sujet ici:
http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#mapfunc
la source
.htaccess
réécritures basées sur des réécritures. Cela ne fonctionne pas dans ce contexte.mod_rewrite peut modifier certains aspects de la gestion des requêtes sans modifier l'URL, par exemple en définissant des variables d'environnement, en définissant des cookies, etc. Ceci est incroyablement utile.
Définissez conditionnellement une variable d'environnement:
Renvoyer une réponse 503:
RewriteRule
l'[R]
indicateur de s peut prendre une valeur non-3xx et renvoyer une réponse non redirigante, par exemple pour les temps d'arrêt / maintenance gérés:renverra une réponse 503 (pas une redirection en soi).
De plus, mod_rewrite peut agir comme une interface super puissante pour mod_proxy, vous pouvez donc le faire au lieu d'écrire des
ProxyPass
directives:Opinion: L'utilisation de
RewriteRule
s etRewriteCond
s pour acheminer des requêtes vers différentes applications ou équilibreurs de charge basés sur pratiquement tous les aspects imaginables de la requête est tout simplement extrêmement puissante. Le contrôle des requêtes en route vers le backend et la possibilité de modifier les réponses en revenant font de mod_rewrite l'endroit idéal pour centraliser toutes les configurations liées au routage.Prenez le temps de l'apprendre, ça vaut vraiment le coup! :)
la source