Redirection, modification d'URL ou redirection HTTP vers HTTPS dans Apache - Tout ce que vous avez toujours voulu savoir sur les règles Mod_Rewrite sans avoir peur de le demander


264

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.


9
L'idée derrière cette question est de donner un chemin serré à toutes les interminables questions mod_rewrite qui rendent fous nos utilisateurs plus habitués. Cela ressemble beaucoup à ce qui a été fait avec les sous- réseaux sur serverfault.com/questions/49765/how-does-subnetting-work .
Kyle Brandt

1
En outre, je ne veux pas vraiment trop de votes positifs sur cette question , ils devraient plutôt aller à la réponse. Je ne veux pas utiliser ceci parce que je veux être sûr que l'affiche obtienne tout le crédit pour ce que j'espère être la réponse mod_rewrite pour mettre fin à toutes les questions mod_rewrite .
Kyle Brandt

4
Désolé, j'ai voté à la question. ;-) Je pense vraiment qu'il faut qu'il apparaisse au sommet (ou presque) des mod-rewriterecherches / filtres de balises.
Steven Lundi

Quelqu'un d'autre (tm) devrait gérer les cas d'utilisation courants. Je ne les connais pas assez pour que justice soit faite.
sysadmin1138

Peut-être que cette question devrait être reliée au wiki de balise de modification de réécriture pour rendre le chemin encore plus court.
Beldaz

Réponses:


224

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 Ondirective doit être donnée car cela active le traitement mod_rewrite. Cela devrait être avant toute autre directive de réécriture.

RewriteCondce qui précède RewriteRulerend cette règle soumise au conditionnel. Toutes les RewriteRules suivantes seront traitées comme si elles n'étaient pas soumises à des conditions.

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

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

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

Le plus complexe RewriteRule contient les conditions pour le traitement. La dernière parenthétique (html|jpg)indique à RewriteRule de correspondre pour htmlou jpg, 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):

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

RewriteBaseest également spécifique à la commande car elle spécifie comment les RewriteRuledirectives 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:

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

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, RewriteRuleil 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:

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 constater, les RewriteBaserè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.

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

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.

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

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

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.

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

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

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.

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

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.

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

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.

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

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 .

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

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

Vous savez comment j'ai dit que cela RewriteConds'applique à une et une seule règle? Eh bien, vous pouvez contourner cela en chaî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 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.

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

Ceci peut être simplifié grâce aux 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]

Correspondra à "ServerFault.com"


9
Bien joué. [remplisseur]
EEAA

3
Très belle mod_rewriteet amorce regex. +1
Steven lundi

3
Il est parfois utile de savoir que le RewriteCondest effectivement traité après la mise en RewriteRulecorrespondance. 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 ..."
Dennis Williamson

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

1
@ sysadmin1138, je pense que cette réponse est bonne mais qu'elle peut être meilleure si vous développez davantage les drapeaux E, N, NS, P, PT et S avec des exemples car ces drapeaux ne sont pas évidents leur fonctionnement, etc.
Pacerier

39

Quels sont le format et la structure fondamentaux des règles mod_rewrite?

Je vais me reporter à l'excellente réponse de sysadmin1138 sur ces points.

De quelle forme / saveur d'expressions régulières ai-je besoin pour bien comprendre?

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.

Quelles sont les erreurs / écueils les plus courants lors de l’écriture des règles de réécriture?

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

  • 500 - Erreur interne du serveur - Supprimez les contrôles chariot Windows dans les fichiers de configuration, le cas échéant, assurez-vous que mod_rewrite est activé (directives d'encapsulation IfModuleconditionnelles pour éviter ce scénario), vérifiez la syntaxe des directives et commentez les directives jusqu'à ce que le problème soit identifié.
  • Boucle de redirection - Utilisez RewriteLog et RewriteLogLevel, commentez les directives jusqu'à ce que le problème soit identifié

Quelle est la bonne méthode pour tester et vérifier les règles mod_rewrite?

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:

<?php
  var_dump($_SERVER);
?>

... 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 RewriteLogdirective mod_rewrite pour consigner l'activité dans un fichier et définissezRewriteLogLevel 3

Existe-t-il des implications des règles mod_rewrite sur le référencement ou la performance dont je devrais être au courant?

AllowOverride allaffecte les performances du serveur, car Apache doit rechercher les .htaccessfichiers 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 .htaccessremplacements 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.

Existe-t-il des situations courantes dans lesquelles mod_rewrite peut sembler être le bon outil pour le travail mais ne l'est pas?

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.

Quels sont quelques exemples courants?

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


Merci pour le lien AskApache. C'est ce que je cherchais!
sica07

Le clown AskApache est officiellement non pris en charge par ASF. Une grande partie de ce qu'il dit est discutable ou tout simplement faux.
Adaptr

@adaptr S'il vous plaît partager les ressources supérieures que vous êtes apparemment au courant.
Danlefree

"Les situations courantes où mod_rewrite peut sembler être le bon outil pour le travail mais ne le sont pas?" - des redirections simples , où mod_rewrite n'est pas déjà utilisé. Utilisez mod_alias Redirectou à la RedirectMatchplace. Voir aussi la documentation Apache: Quand ne pas utiliser mod_rewrite
MrWhite

21

Comme 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_rewritefonctionne et interagit avec le reste d'Apache. Ainsi, au cours des derniers mois, j'ai instrumenté des scénarios de test avec strace+ 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:

  • Certains aspects de la réécriture sont communs à configuration serveur, hôte virtuel, répertoire, .htaccess traitement cependant
  • Certains traitements sont très différents pour la configuration racine (configuration serveur, hôte virtuel et répertoire) par opposition au .htaccesstraitement PerDir ( ).
  • Pire, car le traitement PerDir peut presque indistinctement déclencher le cycle INTERNAL REDIRECT, les éléments de configuration racine doivent être écrits de manière à ce que ce traitement PerDir puisse déclencher cette opération.

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

    • Ces utilisateurs doivent utiliser le .htaccesstraitement / Perdir car il n'y a pas d'alternative disponible.
    • Pire encore, le niveau de compétence de ces utilisateurs (dans la mesure où ils utilisent la logique à relais ladder de mod_rewrite) est généralement nettement inférieur à celui des administrateurs expérimentés.
    • Apache et les fournisseurs d'hébergement n'offrent aucune assistance de débogage / diagnostic. La seule information de diagnostic est une redirection réussie, une redirection vers le mauvais URI. ou un code d'état 404/500. Cela les laisse confus et impuissants.
    • Apache est extrêmement faible, expliquant comment fonctionne la réécriture pour ce cas d'utilisation. Par exemple, il n’explique pas clairement quel .htaccessfichier 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 .htaccessutilisateurs, je pense que nous devons développer et proposer:

  • Description cohérente du fonctionnement réel du système de réécriture dans le traitement PerDir
  • Un ensemble de directives / meilleures pratiques sur la rédaction de .htaccessrègles de réécriture
  • Un analyseur de script de réécriture basé sur le Web très simple, similaire aux analyseurs HTML du W3C, mais qui permet aux utilisateurs de saisir des URI de test ou des vecteurs de test identiques et d’obtenir un journal immédiat du flux logique de réécriture /
  • Conseils pour obtenir des diagnostics intégrés à partir de vos règles (par exemple,

    • Utilisez [E=VAR:EXPR]le fait d’exploiter les EXPRré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:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      

Ceci est bien documenté. Pourquoi dites-vous que la documentation n'explique pas cela?
Adaptr

2
Tout ce que vous avez à faire est de vous abonner aux .htaccesssujets 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 .htaccessré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. :-(
TerryE

Je suis entièrement d'accord. "Nous devons diviser les communautés d'utilisateurs de réécriture en deux catégories et les traiter de manière totalement distincte." Certains utilisateurs utilisent l'hébergement partagé et ont besoin de compter sur eux .htaccess, ce qui est terriblement fragile, compliqué et déroutant, même pour les experts. J'ai encore des problèmes.
Ryan le

15

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:

RewriteMap MapName MapType:MapSource

Par exemple:

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

Vous pouvez ensuite utiliser le nom de carte pour des constructions comme ceci:

${examplemap:key}

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

RewriteMap unescape int:unescape

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

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 dernière phrase n'est pas tout à fait vraie. Le mod_rewritemoteur 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.
TerryE

12

Quelles sont les erreurs / écueils les plus courants lors de l’écriture des règles de réécriture?

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 .


1
Merci pour le lien. En particulier lorsque je travaille avec d'autres membres de l'équipe qui ne sont pas habitués à la réécriture, je trouve que l'ajout d'une <base>balise est plus facile à suivre et permet néanmoins d'activer des chemins relatifs.
dimanche
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.