Expliqué : Comprendre mod_rewrite, la réécriture d'URL et créer de "jolis liens"
P粉501007768
P粉501007768 2023-10-20 15:47:10
0
2
808

Les « Jolis liens » sont un sujet souvent demandé, mais rarement entièrement expliqué. mod_rewrite est une façon de créer de "jolis liens", mais elle est complexe, la syntaxe est très concise, difficile à comprendre et la documentation suppose une certaine familiarité avec HTTP. Quelqu'un peut-il expliquer brièvement comment fonctionnent les « jolis liens » et comment utiliser mod_rewrite pour les créer ?

Autres noms courants, alias, termes pour les URL propres : URL RESTful, URL conviviale, URL conviviale pour le référencement, slugging et URL MVC (peut-être un terme inapproprié)

P粉501007768
P粉501007768

répondre à tous(2)
P粉276064178

Pour développer la réponse de deceze, j'aimerais fournir quelques exemples et une explication de certaines autres fonctionnalités de mod_rewrite. p>

Tous les exemples ci-dessous supposent que vous êtes déjà connecté .htaccess 文件中包含 RewriteEngine On.

Exemple de réécriture

Prenons un exemple :

RewriteRule ^blog/([0-9]+)/([A-Za-z0-9-\+]+)/?$ /blog/index.php?id=&title= [NC,L,QSA]

Cette règle est divisée en 4 parties :

  1. RewriteRule - Commencez à réécrire les règles
  2. ^blog/([0-9]+)/([A-Za-z0-9-+]+)/?$ - C'est ce qu'on appelle un modèle, mais je l'appellerai simplement le côté gauche de la règle - ce que vous voulez remplacer
  3. blog/index.php?id=&title= - appelé substitution, ou le côté droit de la règle de réécriture - ce que vous voulez réécrire
  4. [NC,L,QSA] sont des drapeaux pour réécrire les règles, séparés par des virgules, je les expliquerai en détail plus tard

La réécriture ci-dessus vous permettra de créer un lien vers du contenu comme /blog/1/foo/ et elle se chargera réellement /blog/index.php?id=1&title=foo代码>.

Côté gauche de la règle

  • ^ 表示页面名称的开头 - 因此它将重写 example.com/blog/... 但不会重写 example.com/foo/博客/...^ représente le début du nom de la page - il sera donc réécrit
  • example.com/blog/... mais pas
  • example.com/foo/blog/...(…)
      Chaque ensemble de parenthèses
    • (…) représente une expression régulière, que nous pouvons capturer comme variable sur le côté droit de la règle. Dans cet exemple : ([0-9]+) - 匹配长度至少为 1 个字符且仅包含数字值(即 0-9)的字符串。这可以通过规则右侧的
    • Le premier jeu de parenthèses -
    • ([0-9]+) - correspond à une chaîne d'au moins 1 caractère et ne contient que des valeurs numériques (c'est-à-dire 0-9). Cela peut être référencé via -+ code> (注意 + 用反斜杠转义,因为如果不转义它,这将作为 正则表达式重复字符)。这可以通过规则右侧的 $1 sur le côté droit de la règle
    Le deuxième jeu de parenthèses correspond à une chaîne d'au moins 1 caractère, contenant uniquement des caractères alphanumériques (A-Z, a-z ou 0-9) ou
  • - ou
  • + (remarque ? 表示前面的字符是可选的,因此在本例中 /blog/1/foo//blog/1/foo+ est échappé avec une barre oblique inverse car si vous ne l'échappez pas, cela sera exécuté comme une expression régulière Caractères répétitifs
  • ). Cela peut être référencé via
  • $2 sur le côté droit de la règle$

? signifie que les caractères précédents sont facultatifs, donc dans ce cas

et /blog/1/foo code> seront réécrits à la même position

$ signifie que c'est la fin de la chaîne que nous voulons faire correspondre/blog/1/foo//BLOG/1/ foo/

🎜logo🎜 🎜Ces options sont ajoutées entre crochets à la fin de la règle de réécriture pour préciser certaines conditions. Encore une fois, vous pouvez en savoir plus sur de nombreux indicateurs différents 🎜 dans la 🎜 documentation, mais je vais aborder certains des plus courants : 🎜
NC
L'indicateur 🎜caseless signifie que la règle de réécriture n'est pas sensible à la casse, donc pour l'exemple de règle ci-dessus, cela signifie que 🎜 et 🎜/BLOG/1/foo/ (ou toute variante de celle-ci) seront mis en correspondance. 🎜
L

Le dernier drapeau indique qu'il s'agit de la dernière règle à traiter. Cela signifie que si et seulement si cette règle correspond, aucune autre règle ne sera évaluée lors du traitement de réécriture en cours. Si une règle ne correspond pas, toutes les autres règles seront essayées comme d'habitude. Si vous ne définissez pas l'indicateur L, toutes les règles suivantes s'appliqueront à l'URL réécrite .

END

Depuis Apache 2.4, vous pouvez également utiliser le flag [END]. Les règles correspondant à cela mettront fin [END] 标志。与之匹配的规则将完全终止进一步的别名/重写处理。 (而 [L]complètement

à la suite du traitement d'alias/réécriture. (Et l'indicateur [L] déclenche généralement le deuxième tour, par exemple lors de la réécriture d'un sous-répertoire ou de la réécriture d'un sous-répertoire.)

QSA
/blog/1/foo/?comments=15 这样的内容将加载 /blog/index.php?id=1&title=foo&comments=15L'indicateur d'ajout de chaîne de requête nous permet de transmettre des variables supplémentaires à l'URL spécifiée, qui seront ajoutées aux paramètres d'obtention d'origine. Pour notre exemple, cela signifie quelque chose comme

R
R=301Ce drapeau n'est pas celui que j'ai utilisé dans l'exemple ci-dessus, mais j'ai pensé qu'il valait la peine d'être mentionné. Cela vous permet de spécifier des redirections http et éventuellement d'inclure un code de statut (par exemple ). Par exemple, si vous souhaitez faire une redirection 301 sur /monblog/ vers /blog/, il vous suffit d'écrire une règle comme celle-ci :

RewriteRule ^/myblog/(*.)$ /blog/ [R=301,QSA,L]

Réécrire les conditions

Conditions de réécritureRendez les réécritures plus puissantes, vous permettant de spécifier des réécritures pour des situations plus spécifiques. Vous pouvez en savoir plus à ce sujet dans la 中阅读很多条件>Documentation

, mais je vais passer en revue quelques exemples courants et les expliquer :

# if the host doesn't start with www. then add it and redirect
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
www. (如果尚不存在)并执行 301 重定向。例如,加载 http://example.com/blog/ 会将您重定向到 http://www.example.com/blog/C'est une pratique très courante et ajoutera

devant votre nom de domaine

# if it cant find the image, try find the image on another domain
RewriteCond %{REQUEST_URI} \.(jpg|jpeg|gif|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*)$ http://www.example.com/ [L]
Cette situation est légèrement moins courante, mais c'est un bon exemple de la raison pour laquelle la règle ne sera pas exécutée si le nom de fichier est un répertoire ou un fichier qui existe sur le serveur.
  • %{REQUEST_URI} .(jpg|jpeg|gif|png)$ [NC]
  • Seuls les fichiers portant l'extension jpg, jpeg, gif ou png seront réécrits (insensible à la casse).
  • %{REQUEST_FILENAME} !-f
  • vérifiera si le fichier existe sur le serveur actuel et effectuera une réécriture s'il n'existe pas
  • %{REQUEST_FILENAME} !-d
  • vérifiera si le fichier existe sur le serveur actuel et effectuera une réécriture s'il n'existe pas
  • La réécriture tentera de charger le même fichier sur un autre domaine
🎜
P粉022140576

Pour comprendre ce qu'est mod_rewrite, vous devez d'abord comprendre comment fonctionne un serveur Web. Le serveur web répond à la Requête HTTP. Le niveau le plus basique d'une requête HTTP ressemble à ceci :

GET /foo/bar.html HTTP/1.1

Il s'agit d'une simple demande du navigateur au serveur Web pour une URL /foo/bar.html. Il est important de souligner qu’il ne demande pas de fichier, ​​il demande simplement une URL arbitraire. La requête pourrait également ressembler à ceci :

GET /foo/bar?baz=42 HTTP/1.1

Cela fonctionne aussi bien que les requêtes URL et est évidemment indépendant des fichiers.

Un serveur Web est une application qui écoute sur un port, accepte les requêtes HTTP de ce port et renvoie une réponse. Le serveur Web est entièrement libre de répondre à toute demande de la manière qu'il juge appropriée/de répondre de la manière que vous configurez pour répondre. Cette réponse n'est pas un fichier, mais une Réponse HTTP, qui peut ou non avoir quelque chose à voir avec un fichier physique sur le disque. Il n'est pas nécessaire que le serveur Web soit Apache, il existe de nombreux autres serveurs Web, ce sont simplement des programmes qui s'exécutent de manière persistante et sont connectés à un port qui répond aux requêtes HTTP. Vous pouvez en écrire un vous-même. Le but de ce paragraphe est de vous faire dépasser l’idée selon laquelle une URL est directement équivalente à un fichier, ce qui est très important à comprendre. :)

La configuration par défaut de la plupart des serveurs Web consiste à rechercher un fichier sur votre disque dur qui correspond à une URL. Si la racine du document du serveur est définie sur /var/www,它可能会查找文件/var/www/foo/bar. html existe, servez-la si elle existe. Si le fichier se termine par ".php", il appellera l'interpréteur PHP et renverra le résultat. Toutes ces associations sont entièrement configurables ; il n'est pas nécessaire que le fichier se termine par ".php" pour que le serveur Web l'exécute via l'interpréteur PHP, et l'URL n'a pas besoin de correspondre à un fichier spécifique sur le disque pour que quelque chose se produise.

mod_rewrite est une méthode de réécriturede traitement des requêtes internes. Lorsque le serveur Web reçoit une demande pour l'URL /foo/bar, vous pouvez réécrire cette URL en autre chose et le serveur Web recherchera un fichier sur le disque qui lui correspond. Exemple simple :

RewriteEngine On
RewriteRule   /foo/bar /foo/baz

Cette règle signifie chaque fois qu'une requête correspond à "/foo/bar", réécrivez-la en "/foo/baz". La demande sera ensuite traitée comme /foo/baz. Cela peut être utilisé pour divers effets tels que :

RewriteRule (.*) .html

Cette règle correspond à n'importe quoi (.*) 并捕获它 ((..)),然后重写它以附加“.html” ”。换句话说,如果 /foo/bar 是请求的 URL,则将按照 /foo/bar.html.*) et le capture (

(..)), puis le réécrit pour ajouter ".html". En d'autres termes, si

est celui demandé. URL, elle sera traitée comme si elle avait été demandée. Voir

http://regular-expressions.info🎜 pour plus de détails sur la correspondance, la capture et le remplacement des expressions régulières. 🎜Une autre règle souvent rencontrée est : 🎜
RewriteRule (.*) index.php?url=

Cela correspond à nouveau à n'importe quoi et le réécrit dans le fichier index.php et la requête originale dans url 查询参数中附加最初请求的 URL。即,对于传入的任何和所有请求,都会执行文件index.php,并且该文件将有权访问 $_GET['url'] afin qu'il puisse en faire ce qu'il veut.

Tout d'abord, vous mettez ces règles de réécriture dans votre fichier de configuration de serveur Web. Apache vous permet également* de les mettre dans un fichier appelé .htaccess à la racine du document (c'est-à-dire à côté du fichier .php).

* si cela est autorisé par le fichier de configuration principal d'Apache, il est facultatif mais généralement activé.

mod_rewrite ne fait rien

mod_rewrite ne rendra pas comme par magie toutes les URL « jolies ». Il s’agit d’une idée fausse courante. Si vous avez ce lien sur votre site web :

mod_rewrite ne peut pas le rendre joli. Afin d'en faire un beau lien vous devez :

  1. Changez le lien en un beau lien :

  2. Utilisez l'une des méthodes ci-dessus pour utiliser mod_rewrite sur le serveur afin de gérer les demandes d'URL /my/pretty/link.

(Vous pouvez utiliser mod_substitute conjointement avec la transformation de la page HTML sortante et des liens qu'elle contient. Bien que cela soit généralement plus laborieux que la simple mise à jour de la ressource HTML.)

mod_rewrite peut faire beaucoup de choses, vous pouvez créer des règles de correspondance très complexes, notamment enchaîner plusieurs réécritures, transmettre des requêtes par proxy à des services ou des machines complètement différents, renvoyer des codes d'état HTTP spécifiques en tant que réponses, rediriger les requêtes, etc. Il est très puissant et peut être très utile si vous comprenez le mécanisme de base de réponse aux requêtes HTTP. Cela ne rend pas automatiquement vos liens jolis.

Veuillez vous référer à la

documentation officiellepour tous les drapeaux et options possibles.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal