Je suis sur un hébergement partagé bon marché avec Apache et j'essaie de réécrire avec .htaccess
:
http://anything.example.com/par1/par2
=> http://example.com/anything/index.php?a=par1&b=par2
Pour ce faire, j'ai le fichier .htaccess
suivant dans le répertoire racine:
RewriteEngine on
RewriteCond %{HTTP_Host} ^(.*)\.example\.com
RewriteRule ^(.*)$ http://example.com/%1/$1 [L,NC,QSA]
RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ $1/index.php?section=$2&page=$3 [L]
Et cela fonctionne réellement. Le problème est que si je mets http://digitalcameras.example.com/nikon/123
dans la chaîne d'adresse du navigateur Web et que j'appuie sur Entrée, la chaîne devient la suivante:
http://example.com/digitalcameras/nikon/123
(Notez que la partie digitalcameras
s'est déplacée du début au milieu).
index.php
placé dans le dossier /digitalcameras
.
La question est donc la suivante: puis-je faire la même chose sans changer l'adresse dans le navigateur?
RewriteRule ^(.*)$ http://example.com/%1/$1 [L,NC,QSA]
Lorsque vous spécifiez une URL absolue (schéma + nom d’hôte) dans la substitution RewriteRule
, un événement est implicitement déclenché (== --- ==). ) redirection externe - qui correspond à ce que vous voyez.
Cependant, si le ou les sous-domaines et le domaine principal sont tous sur le même compte d'hébergement partagé (c'est-à-dire le même système de fichiers), vous ne devriez pas avoir à spécifier explicitement le domaine complet dans la substitution . , spécifiez simplement le chemin du système de fichiers.
Par exemple:
RewriteRule (.*) /%1/$1 [L]
Les drapeaux NC
et QSA
sembleraient superflus ici. La chaîne de requête est ajoutée par défaut, sauf si vous incluez explicitement une chaîne de requête dans la substitution . Et les ancres de modèle (^
et $
) ne sont pas nécessaires non plus lorsqu’on utilise un modèle de correspondance tout .*
.
PDATE # 1: Le premier RewriteRule
semblerait superflu. Il s’agit d’un sous-domaine générique . Je suppose donc que ce sous-domaine pointe vers la même racine de document que le domaine principal.
Ce que vous essayez réellement de faire est de récrire en interne http://anything.example.com/par1/par2
sur /anything/index.php?a=par1&b=par2
sur le même sous-domaine .
Essayez plutôt ce qui suit:
RewriteEngine on
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{HTTP_Host} ^(.*)\.example\.com [NC]
RewriteRule ^([^/.]+)/([^/.]+)/?$ %1/index.php?section=$1&page=$2 [L,QSA]
Le drapeau QSA
est requis ici, si la requête d'origine (jolie URL) peut avoir une chaîne de requête, qui doit être transmise.
Pas besoin d'échapper au point dans une classe de caractères pour correspondre à un point littéral.
La directive RewriteCond
qui contrôle la variable d’environnement REDIRECT_STATUS
empêche une boucle de réécriture potentielle (qui entraînerait une erreur 500 dans le navigateur).
PDATE # 2: Pour éviter l'utilisation explicite du domaine (par exemple, example.com
), vous pouvez simplement faire correspondre le premier segment de domaine, c'est-à-dire. jusqu'au premier point. Par exemple:
RewriteCond %{HTTP_Host} ^([^.])+
Cependant, cela correspondrait également au domaine apex principal (ou www
), sauf si vous avez déjà une directive pour le bloquer. Je suppose que l'accès au domaine principal comme ceci serait strictement invalide? Cependant, cela peut être correct si votre script gère une telle requête non valide avec un 404?
Ou, pour ne faire correspondre que les sous-domaines du domaine principal, à l'exception de www
, essayez ensuite:
RewriteCond %{HTTP_Host} !^www\. [NC]
RewriteCond %{HTTP_Host} ^([^.])+\.[a-z-]\.(com|co\.uk|net) [NC]
Vous auriez besoin d'ajouter les TLD comme requis (peut-être pourrait-on généraliser davantage?).