Calocybe: Lösung für das leidige Umlautproblem bei Formularübergabe an PERL

Beitrag lesen

Der Meinung bin ich auch. Bernhard sollte mal die Zeichensatz-
Einstellungen seines IE5 checken. Wenn er sie zurueck auf ISO-8859-1
stellt, gibt's da vermutlich keine Probleme mehr. Jedenfalls haengt
das ganz sicher nicht mit URL-Encoding oder sowas zusammen.

Ja gern, aber nur wo ??

Keine Ahnung, hab keinen IE, und weiss nicht, wie man den konfiguriert.

Output:

AUTH_TYPE:  
BLASTER:  A220 I10 D1 H1 P300 T6
[ usw. ]
WINBOOTDIR:  C:\WINDOWS
WINDIR:  C:\WINDOWS

Tja, hab leider nichts verdaechtiges gefunden. Ich hatte gehofft, dass eine Variable wie CONTENT_TYPE gesetzt ist, aber das war wohl nichts.

Meine Frage nun: wenn ich diese Funktion nicht aufrufe, schreibt er mir ä,ü,ö, usw. hin. Wenn man nochmal einen Blick auf den Query wirft, müsste er dann aber doch %BC%C3%9C% ausgeben oder?

Das ist eben das, was der Ausdruck s/%([a-fA-F0-9][a-fA-F0-9])/pack('C',hex($1))/eg erledigt (siehe folgenden Text).

Oder ist es vielleicht so, dass javascript seine Parameter mit unicode encoded, und PERL mit einer anderen Methode seine Parameter decoded, welche wiederum die Javascript-encoded Daten nicht decoden kann, und daher diese komischen Zeichen als ganz normale Characters decoded, wobei noch schlimmere Zeichen rauskommen? - Das war jetzt ziemlich unverständlich oder??

Ich glaube, da liegt ein ziemliches Verstaendnisproblem bei Dir vor. Es ist einfach so, dass in einer URL nicht alle Zeichen erlaubt sind. Z.B. duerfen Leerzeichen oder Umlaute in einer URL nicht vorkommen. Will man solche Zeichen doch uebergeben, muss man sie auf der Clientseite codieren und auf der Serverseite wieder entsprechend decodieren. Das hat erstmal noch nichts mit dem Thema Unicode/Zeichensaetze zu tun, sondern ist einfach HTTP. Diese Codierung geschieht, indem man von dem Zeichen den hexadezimalen ASCII-Code nimmt, ein Prozentzeichen davorsetzt und das dann in die URL schreibt. Ein Leerzeichen hat den ASCII-Code 32 dezimal, das ist 20 hexadezimal, also wird es mit %20 in der URL notiert. (Ausgerechnet beim Leerzeichen ist es weitverbreitet, dieses nun doch nicht mit %20, sondern mit einem einfachen + zu codieren. Das ist aber nirgendwo standardisiert und sollte deshalb bei einem Encoding nicht verwendet werden, wohl aber beim Decoding unterstuetzt, um Kompatibilitaet zu gewaehrleisten.) Das %-Zeichen selbst wird dann mit %25 codiert, da 25 hex == 37 dez der Zeichencode dieses Zeichens ist. Wenn jetzt so eine URL bzw. so ein QueryString beim Server ankommt, muss der/die natuerlich decodiert werden, und das macht man in Perl gewoehnlich mit dem regulaeren Ausdruck s/%([a-fA-F0-9][a-fA-F0-9])/pack('C',hex($1))/eg. Das CGI-Modul macht uebrigens auch nichts anderes (nur darfst Du's natuerlich nicht nochmal machen, wenn dies vom modul bereits durchgefuehrt wurde).

Soweit funzt das normalerweise ganz gut, nur kommt jetzt das Zeichensatzproblem. Woher weiss man denn, welchen (ASCII-)Code ein Zeichen hat? Dafuer gibt es sog. Zeichensaetze, die den Zeichen Nummern zuordnen. ASCII ist nur einer von vielen Zeichensaetzen, allerdings sind die ersten 128 Zeichen (mit den Codes 0 bis 127) in fast allen Zeichensaetzen dieselben (dies gilt z.B. nicht fuer EBCDIC, aber wen interessiert das schon). Ab dem Code 128 allerdings unterscheiden sich die verschiedenen Charsets (= Character sets = Zeichensaetze). Einige davon findest Du auf <../../thb.htm>. Da hierzulande meist der iso-8859-1 set verwendet wird, wird z.B. ein ü gewoehnlich mit %FC (252) encodet.

Der von Dir verwendet Unicode-Zeichensatz ist nun aber ganz anders. Er verwendet fuer manche Zeichen nicht nur ein Byte pro Zeichen, sondern zwei. Deshalb kann er auch nicht nur 256 Zeichen darstellen, sondern... na jedenfalls mehr. Das heisst aber auch, dass Dein Browser gleich zwei Bytes codieren muss, um z.B. einen Umlaut im QueryString zu uebergeben. So hat er z.B. bei Dir aus einem Ö die Sequenz %C3%96 gemacht. Nun geht Dein Perlscript beim decodieren aber von einem Zeichensatz mit nur einem Byte aus. Deshalb wird diese Sequenz zu zwei Zeichen dekodiert, naemlich à und -.

Alles klar? ;-)

Ein bessere Moeglichkeit als Deine sub encode() (die vielleicht besser decode heissen sollte) weiss ich nun auch nicht. Leider fehlt ja die information, welcher Zeichensatz verwendet wird.

So long