Tohle je další z problémů nad jejichž řešením jsme v poslední době strávili nějaký čas.
Pokud máme v URL hodnoty, které obsahuje speciální znaky (například ?, &, +, …) je nutné tyto hodnoty při sestavení URL escapovat nahradit je za ekvivalentní zápis pomocí %xx (viz RFC1738).
Problém nastal v případě, že jsme takovéto URL zpracovávali pomocí mod_rewrite (hezká URL kvůli SEO). Přestože jsme URL do HTML vygenerovali správně escapované do systému nám dorazilo opět se speciálními znaky. Nakonec jsme zjistili, že problémem je právě přepis pomocí mod_rewrite.
Mějme například následující jednoduché pravidlo:
RewriteRule ^/page/(.*)$ page.php?title=$1
Pokud přes takovéto pravidlo projde URL obsahující escapovanýspeciální znak výsledkem bude nové URL, ve které bude tento znak opět zapsaný přímo. Důvodem je, že pro účely rewriteRule provádí mod_rewrite automatické odescapování řetězců.
Po chvíli hledání na google jsme zjistili, že nejsme jediní, kdo měl tento problém. Viz například:
http://www.dracos.co.uk/code/apache-rewrite-problem/
http://tools.cherrypy.org/wiki/ModRewrite
Jako nejlepší možnost se nám jevilo zamozřejmně použít escapování pomocí RewriteMap. Podle návodů mělo stačit doplnit do httpd.conf:
RewriteMap escape int:escape
A v .htaccess pak pouívat pravidla ve formátu:
RewriteRule ^/page/(.*)$ page.php?title=${escape:$1}Bohužel tento postup nefungoval. Hodnoty v URL byla stále překládány na hodnoty bez escapování. Nepodařilo se nám zjistit důvod. Pokud někdo máte nějaký nápad co by mohlo být příčinou tohoto chování budu rád pokud mi v příspěvcích pod článkem poradíte. Protože jediné řešení, které pro nás nakonec připadalo v úvahu bylo zakázání speciálních znaků v hodnotách se kterými je prováděn překlad pomocí mod_rewrite.
Chyba je v mod_rewrite - kdyz de-escapuje tak znak jako & nenechava v hexa tvaru (%26), ale prepisuje na &.
Napr. z retezce a=1&b=2%26c=3 (mineho jako a='1' a b='2&c=3') se udela a=1&b=2&c=3 ktery lze postupne matchovat v RewriteRule, coz je pekna blbost, protoze se 2 rozdilne znaky, & jako oddelovac a & jako pismenko, mapuji na jednu a tutez hodnotu..
Zkuste poslat bug report pro tvurce mod_rewrite :) A pak vas zbytek sveta sezere protoze jste jim narusili funkcnost spatne napsanych rewrite skriptu..
Rada by byla.
Django
http://docs.djangoproject.com/en/dev/topics/http/urls/
BTW: Dnes už se přeci dá obejít i bez ?, &, +, znaků v URL.
A proměnné, šifrovaně s nimi do POSTu :-)
Ja to resim tak..priklad uz do dat.tabulku si pripravim column pagename a napriklad pri ukladani clanku si nazev upravim treba tak "clanek-rady-v-php"...a pak odpada parsovani primo na scriptu..a data z dat. pak volam pomoci pagename kterou preda mod_rwrite...v jinych pripadech mi ovsem nezbyva nez parsovat primo na scriptu
Autor je student Fakulty informačních technologií VUT v Brně. Současně pracuje ve firmě LifeWeb (http://www.lifeweb.cz) jako hlavní vývojář.