pondělí 17. února 2003

Funkce escape a mezinárodní znaky v URL

Několik posledních dní jsem se zabýval otázkou jak přenášet metodou GET (potažmo v URL) české znaky. Tento problém jsem sice řešil v kontextu našeho HTTP serveru Jetty, nicméně závěry, ke kterým jsem došel jsou všeobecné.

Ve specifikaci URL není nikde řečeno jaké kódování se použije pro mezinárodní znaky. Ony by se totiž, žádné jiné znaky mimo sadu US-ASCII ani používat neměly. Představte si situaci, kdy používáte například vyhledávání nějakého zeměpisného místa a potřebujete do URL dostat Kunžak. Pro tento účel byla v JavaScriptu 1.0 specifikována funkce escape. Tato funkce má jeden jediný argument a to řetězec, který se zakóduje do hexadecimálních escape sekvenci. V našem případě by se tedy do URL nemělo dostat přímo Kunžak, ale jeho zakódovaná escape sekvence . Takhle by to mělo fungovat teoreticky, praxe je bohužel jiná.

Funkcí escape jsme sice zakódovali české znaky, ale už jsme neřekli v jakém kódování jsme tak učinily, escape("ž") v UTF-8 vrací úplně jiné číslo než escape("ž") ve Windows-1250. Otázkou zůstává jaké kódování se použije? Našinec si odpoví, asi by to mělo rozhodnout nastavení kódování html stránky, jinak řečeno charset. Chyba lávky, Internet Explorer (testováno na verzi 5.00.3315.1000, SP2;q319182;Q321232;Q323759;Q328970;) si kódování stránky ignoruje a pro escape používá stále Windows-1250, v Mozille se to chová tak jak bychom předpokládali, tedy výsledná escape sekvence je řízena kódováním stránky.

Ve specifikaci ECMAScriptu verze 3.0 je tato funkce označená, za zastaralou a nedoporučuje se jí používat. Zároveň je nahrazena funkcí encodeURI, která je už ovšem specifikována tak, že pro kódování je vždy použito UTF-8. To je dobře vzhledem ke snaze IETF, která pracuje na návrhu přechodu URL na IRI, který by mimo jiné specifikoval použití kódování UTF-8 jako standardu pro escape sekvence.

Celý problém jsem nakonec vyřešil tak, že jsem si napsal vlastní konverzní funkci, která převede české znaky na escape sekvence v UTF-8. České znaky jsou nahrazeny z tabulky konstant s escape sekvencemi v UTF-8, které mám předem „natvrdo“ předdefinované.