problème avec les caractères utf-8 et les règles de réécriture apache2

Je vois le post validant utf-8 dans la règle de réécriture de htaccess et je pense que c’est génial, mais un problème plus fondamental que je rencontre en premier:

J’avais besoin d’étendre pour gérer les caractères utf-8 pour les parameters de chaîne de requête, les noms de répertoires, de fichiers et utilisés dans les affichages pour les utilisateurs, etc.

J’ai configuré mon Apache avec DefaultCharset utf-8 et aussi mon php si cela est important. Ma règle de réécriture originale a tout filtré sauf les A-Za-z et les tirets bas et les tirets. et ça a fonctionné. Quelque chose d’autre vous donnerait un 404 (ce qui est ce que je veux!) Maintenant, cependant, il semble que tout corresponde, y compris des choses que je ne veux pas, cependant, même si cela semble ne pas aller dans la chaîne de requête est une chaîne de caractères A-Za-z_- régulière.

Je trouve cela déroutant, car la règle dit de mettre tout ce que vous avez associé dans la chaîne de requête:

Voici la règle d’origine:

RewriteRule ^/puzzle/([A-Za-z_-]+)$ /puzzle.php?g=$1 [NC] 

et voici la règle révisée:

 RewriteRule ^/puzzle/(\w+)$ /puzzle.php?g=$1 [NC] 

J’ai fait le changement parce que quelque part j’ai lu que \ w correspond à TOUS les caractères alpha où A-Zetc. ne correspond qu’à ceux sans accent et trucs.

Peu importe laquelle de ces règles j’utilise:

Dans l’application, j’ai ceci:

 echo $_GET['g']; 

Si je lui donne une URL comme http://mydomain.com/puzzle/USA, cela fait écho à “USA” et fonctionne bien.
Si je lui donne une URL comme http://mydomain.com/puzzle/Mexico, cela ne fait rien et avertit que l’index g n’est pas défini et bien sûr, il n’a pas de ressources pour le Mexique.
si je lui donne une URL comme http://mydomain.com/puzzle/fuzzle/buzzle/j.qle, il fait la même chose.
Ce dernier cas devrait être un 404!

Et cela le fait, quelles que soient les règles ci-dessus que j’utilise. J’ai configuré un journal de réécriture

  RewriteLogLevel 5 RewriteLog /opt/local/apache2/logs/puzzles.httpd.rewrite 

mais c’est vide.

Voici le journal d’access régulier (il donne un statut de 200)

 [26/May/2010:11:21:42 -0700] "GET /puzzle/M%C3%A9xico HTTP/1.1" 200 342 [26/May/2010:11:21:54 -0700] "GET /puzzle/M/l.foo HTTP/1.1" 200 342 

Que puis-je faire pour obtenir ces $% # $ @ (* # @ !!! caractères mais pas slash, dot ou autre non-alpha dans mon programme, et une fois là-bas, les décodera-t-il correctement? Y a-t-il autre chose que je dois configurer?

Sur…

 RewriteRule ^ / puzzle / (\ w +) $ /puzzle.php?g=$1 [NC]

Quelqu’un me corrige si je me trompe, mais cela ne signifie-t-il pas que les requêtes demandant des sous-répertoires contournent simplement cette règle?

De même, une manière paresseuse de résoudre ce problème consiste à regrouper également le caractère ‘%’. Autant que je sache, tout ce que vous êtes autorisé à utiliser est sur n’importe quel chemin URL est l’encodage URL. En fait, voir: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm

Je suis sûr qu’il y a des moyens plus avancés et meilleurs pour le faire, mais cela devrait résoudre votre problème immédiat.

Ceci est une réponse à la réponse du destroyer mais elle est trop longue.

Je suis en bas avec l’URL encodant l’unicode parce qu’il est assez facile de le décoder pour l’affichage. Alors peut-être que c’est le problème fondamental. Finalement, je vais juste utiliser url_encode en php pour le faire, mais je pensais essayer un en ligne juste pour tester des choses: je suis allé sur http://www.opinionatedgeek.com/dotnet/tools/urlencode/Encode.aspx et essayé de coder México et il est sorti M% c3% a9xico. Je suis allé sur le site que vous avez indiqué et essayé et il est sorti M% E9xico différent !! Lequel est-ce??? Je suppose que je devrais accepter tout ce que la fonction php me donnerait. Mais tous les deux ont un 9 dans ce qui signifie que je dois accepter les chiffres aussi bien que%. Est-ce tout ce que je devrais inclure?

J’espère que les requêtes demandant des sous-répertoires authentiques NE correspondront PAS à cette règle si c’est ce que vous voulez dire en le contournant, je préférerais plutôt qu’elles rendent les pages statiques dans les sous-répertoires. C’est pourquoi je veux vraiment exclure / ce que je pensais avoir fait. Mais semble correspondre à quelque chose après les sous-répertoires / en incluant les sous-répertoires et aller dans le fichier puzzle.php.

Voici ce que j’ai essayé, mais pas de joie: j’ai utilisé cette règle: RewriteRule ^ / puzzle / ([A-Za-z0-9 _% -] +) $ /puzzle.php?g=$1 [NC] comme vous le voyez ajouté le% et 0-9 au groupe. Dois-je échapper au% ou à quelque chose? Je lis que seulement \ a besoin de s’échapper entre crochets. J’espère que c’est ce que tu veux dire. Serait-ce le seul caractère supplémentaire que vous obtiendriez en encodant une chaîne Unicode possible? puis j’ai passé les 2 versions différentes codées en url du Mexique. Pour M% E9xico, je reçois maintenant 404 et ce message: L’URL / puzzle / México demandé n’a pas été trouvé sur ce serveur. Pour M% c3% a9xico, je reçois maintenant ce message sur le 404: L’URL / puzzle / Mexique demandé n’a pas été trouvée sur ce serveur. Et pour les sous-répertoires inexistants, il donne maintenant 404 comme il se doit. Alors maintenant, c’est juste la règle de réécriture qui ne fonctionne pas. C’est du progrès. Le journal de réécriture a également commencé à contenir des éléments: en voici quelques-uns. Je vais google pour savoir comment lire ces logs:

 kidd108d-mac3:logs tpdick$ cat puzzles.httpd.rewrite ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (2) init rewrite engine with requested uri /puzzle/M?xico ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) applying pattern '^/puzzle/([A-Za-z0-9_%-]+)$' to uri '/puzzle/M?xico' ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (1) pass through /puzzle/M?xico ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/M?xico ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] ssortingp per-dir prefix: /Users/tpdick/Sites/puzzles/puzzle.php/M?xico -> puzzle.php/M?xico ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] applying pattern '^(.*)/GeoP-Test/puzzle/(.*)$' to uri 'puzzle.php/M?xico' ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (1) [perdir /Users/tpdick/Sites/puzzles/] pass through /Users/tpdick/Sites/puzzles/puzzle.php ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/M?xico ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] ssortingp per-dir prefix: /Users/tpdick::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (2) init rewrite engine with requested uri /puzzle/México ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) applying pattern '^/puzzle/([A-Za-z0-9_%-]+)$' to uri '/puzzle/México' ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (1) pass through /puzzle/México ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/México ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] ssortingp per-dir prefix: /Users/tpdick/Sites/puzzles/puzzle.php/México -> puzzle.php/México ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] applying pattern '^(.*)/GeoP-Test/puzzle/(.*)$' to uri 'puzzle.php/México' ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (1) [perdir /Users/tpdick/Sites/puzzles/] pass through /Users/tpdick/Sites/puzzles/puzzle.php ::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/México 

Maintenant quoi??

Je vous suggère d’activer MultiViews et d’oublier mod_rewrite. Ajoutez à votre configuration apache dans la section appropriée Directory / VirtualHost :

 Options +MultiViews #should already be set to this, but it doesn't hurt: AcceptPathInfo Default 

Non, vous pouvez toujours omettre les extensions tant que le client inclut le type MIME correspondant dans son en-tête Accept.

Maintenant, une demande pour /puzzle/whatever /puzzle.php sera /puzzle.php à /puzzle.php et $_SERVER['PATH_INFO'] sera remplie avec /whatever .


Si vous voulez le faire avec mod_rewrite c’est aussi possible. La chaîne de test de RewriteRule n’est pas échapée (les parties% xx sont converties en octets réels). Vous pouvez obtenir la chaîne d’ %{THE_REQUEST} origine en utilisant %{REQUEST_URI} ou %{THE_REQUEST} (la dernière contient également la méthode et la version HTTP).

Par convention, les navigateurs Web utilisent le codage UTF-8 dans les URL. Cela signifie que “Mexico” sera encodé en M%C2%82xico , pas M%82xico , ce qui serait prévisible si les navigateurs utilisaient ISO-8859-1. De plus, [a-zA-Z] ne correspondra pas à é . Cependant, cela devrait fonctionner:

 RewriteCond %{REQUEST_URI} ^/puzzle/[^/]*$ RewriteRule ^/puzzle/(.*)$ /puzzle.php?q=$1 [B,L] 

Vous avez besoin de B pour échapper à la référence arrière, car vous l’utilisez dans une chaîne de requête, dans laquelle l’ensemble des caractères autorisés est inférieur à celui du rest de l’URI.

Ce que vous devez savoir, c’est que RewriteRule n’est pas unicode. Tout autre que .* Peut donner (potentiellement) des résultats incorrects. Même [^/] peut ne pas fonctionner car le caractère ” / ” (read: byte) peut faire partie d’une séquence de caractères multi-octets. Si RewriteRule était unicode, votre solution avec \w devrait fonctionner.

Comme vous ne voulez pas faire correspondre les sous-répertoires et que RewriteRule ^/puzzle/[^/]* n’est pas une option, cette vérification est renvoyée à un RewriteCond qui utilise le %{REQUEST_URI} .

Cette solution est basée sur: http://www.dracos.co.uk/code/apache-rewrite-problem/

Essayez ces règles de réécriture:

 AddDefaultCharset UTF-8 RewriteEngine On RewriteCond %{THE_REQUEST} /puzzle/([^?\ /]+) RewriteRule ^puzzle/(.*)$ puzzle.php/%1 [L] 

Comment obtenir le paramètre de requête:

 g: $g

"; // Test if '/' is present in URL for 404's $g2 = substr($_SERVER['REQUEST_URI'], 8); if (strpos($g2, '/') === false) { // do stuff } else { // Send 404 header here echo "

404

"; } ?>

Avec cette solution, vous devez envoyer le 404 à partir de PHP.

travailler avec CodeIgniter et le fichier vietnamien utf-8 (Tiếng Viết) .htaccess:

 RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+[az,AZ,0-9,ễ].+)$ index.php/$1 [L] 

quand url a ”n’ alors erreur => RewriteRule a ‘ễ’

testez-le ([^/]+) cela peut fonctionner pour vous