Comment encoder les caractères spéciaux à l'aide de mod_rewrite & Apache?
Je voudrais avoir des URLs propres pour mon système de marquage le long avec tous les caractères spéciaux: +
, &
, #
, %
, et =
. Est-il un moyen de le faire avec mod_rewrite sans avoir à double-encoder les liens?
Je remarque que delicious.com et stackoverflow semblent être en mesure de traiter séparément codé en caractères spéciaux. Quelle est la formule magique?
Voici un exemple de ce que je veux:
http://www.foo.com/tag/c%2b%2b
Déclencherait la suite RewriteRule:
RewriteRule ^tag/(.*) script.php?tag=$1
et la valeur de la balise serait "c++"
Le fonctionnement normal de l'apache/mod_rewrite ne fonctionne pas comme ça, comme il semble à son tour le signe plus dans des espaces. Si je double coder le signe plus à '%252B' puis-je obtenir le résultat souhaité - mais il s'agit d'une malpropre URL et semble assez hacky pour moi.
Vous devez vous connecter pour publier un commentaire.
Je ne pense pas que c'est tout à fait ce qui se passe. Apache est le décodage de l' %2Bs à +s dans le chemin d'accès de la partie depuis + est un caractère valide là. Elle le fait avant de laisser mod_rewrite look à la demande.
Alors mod_rewrite changements de votre demande/tag/c++' à 'script.le php?tag=c++. Mais dans une chaîne de requête composant de l'application/x-www-form-format codé, l'échappement, les règles sont très légèrement différentes de celles qui s'appliquent dans le chemin d'accès de pièces. En particulier, '+' est un raccourci de l'espace (qui pourrait tout aussi bien être codé comme '%20', mais c'est une vieille comportement, nous ne serez jamais en mesure de changer maintenant).
Donc, PHP formulaire de lecture de code reçoit le 'c++' et la déverse dans votre _GET comme C-espace-de l'espace.
Ressemble à la façon de contourner ce problème est d'utiliser le rewriteflag 'B'. Voir http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteflags - curieusement il utilise plus ou moins le même exemple!
+
signifie littéralement un plus, et donc c'est sémantiquement équivalent à%2B
.+
ne représente qu'un espace dans la requête de la partie (application/x-www-form-url-encodé règles au lieu de pure URL règles).C++ Stack Overflow
. Parce que c'est actuellement le problème, je vais essayer de surmonter remise en question ici.Je ne suis pas sûr de comprendre ce que vous demandez, mais le
NE
(noescape) drapeau de ApacheRewriteRule
directive pourrait être de quelque intérêt pour vous. Fondamentalement, il empêchemod_rewrite
automatiquement à partir de l'échappement des caractères spéciaux dans la substitution de motif que vous fournissez. L'exemple donné dans l'Apache 2.2 documentation estqui se tourner, par exemple,
/foo/zed
dans une redirection vers/bar/arg=P1%3dzed
, de sorte que le script/bar
verrez alors un paramètre de requête nomméearg
avec une valeurP1=zed
, si elle regarde dans saPATH_INFO
(bon d'accord, ce n'est pas un réel paramètre de requête, ainsi sue moi ;-P).Au moins, je pense que c'est la façon dont il fonctionne . . . Je n'ai jamais utilisé ce drapeau de moi-même.
J'ai enfin fait ce travail avec l'aide de RewriteMap.
Ajouté la fuite de la carte dans httpd.fichier conf
RewriteMap es int:escape
et l'a utilisé dans la règle de Réécriture
Le problème sous-jacent est que vous vous déplacez d'une demande qui a un codage (plus précisément, un signe est un signe plus) dans une demande d'encodage différent (un signe représente un espace). La solution est de contourner le décodage que le mod_rewrite ne et convertir votre chemin directement à partir de la demande brute à la chaîne de requête.
De dérivation de l'écoulement normal des règles de réécriture, nous allons charger la demande brute de chaîne directement dans une variable d'environnement et de modifier la variable d'environnement au lieu de réécrire le chemin. C'est déjà codé, donc nous n'avons généralement pas besoin de s'inquiéter à propos de l'encodage quand on se déplace à la chaîne de requête. Ce que nous voulons, cependant, est de pour cent-encoder les signes plus afin qu'ils soient correctement relayé comme les signes plus et pas des espaces.
Les règles sont extrêmement simples:
Cette triviale script.php confirme que cela fonctionne:
Je rencontre le même problème pour mod_rewrite avec le signe + dans l'url. Le scénario, comme ci-dessous:
nous avons une url avec le signe + besoin de réécrire comme
http://deskdomain/2013/08/09/a+b+c.html
RewriteRule ^/(.*) http://mobiledomain/do/urlRedirect?url=http://%{HTTP_HOST}/$1
Les jambes de suspension de l'action urlRedirect obtenir les paramètres d'url, faire un peu de changement et à l'aide de l'url pour rediriger un autre. Mais req.getParameter("url") le signe + changement à vide, le paramètre de l'url du contenu est
http://deskdomain/2013/08/09/a b c.html
, que de provoquer redirection 404 not found. Pour le résoudre, il (obtenir de l'aide avant de répondre)nous utilisons réécriture du pavillon B (échappement des références arrières), et NE (noescape)RewriteRule ^/(.*) http://mobiledomain/do/urlRedirect?url=http://%{HTTP_HOST}/$1 [B,NE]
Le B échappe + pour %2B , NE permettra d'éviter mod_write échapper %2B %252B (échappement double signe+), donc dans
req.getParameter("url")=http://deskdomain/2013/08/09/a+b+c.html
Je pense que la raison est req.getParameter("url") va faire un ne pas encoder pour nous, le signe + peut ne pas encoder à vide.
Vous pouvez essayer de ne pas encoder %2B une fois de + , alors ne pas encoder + encore une fois à vide.
"%2B" unescape-> "+" unescape-> " "