Mark: bzw. (BROWSER) Maskierte Sonderzeichen übergeben

Hallo!
Ich habe auf meiner Seite Thumbnails, um Bilder vergrößert darzustellen. Beim anklicken auf diese wird einem Perl-Script die Adresse des vergrößerten Bildes und ein Bildtitel übergeben. Das geht soweit auch ganz gut.
Probleme gibt's aber z.B. mit Umlauten: Wenn dem Perl-Script ein Titel mit Umlauten übergeben wird, erscheint er Fehlerhaft, zumindest mit OPERA (mit MOZILLA ist's O.K.).
Was stimmt da nicht? Liegt der Fehler etwa am OPERA-Browser? Wie ist es mit dem IE?

Hier ein Beispiel, damit die Sache klarer wird:
Thumbnail-Link: http://www.postbus.de/cgi-bin/foto.pl?bild=sechura.jpg&titel=in+der+Sechura-Wüste,+Peru&seite=peru.shtml
Im Opera erscheint nun folgender Bildtitel: in der Sechura-Wüste, Peru

Schon mal danke, noch ein schönes WE & Gruß: Mark

  1. ... hoppla, der Link wird irgendwie abgeschnitten! Hab' ihn mal als URL eingetragen...

  2. Hoi,

    Probleme gibt's aber z.B. mit Umlauten: Wenn dem Perl-Script ein Titel mit
    Umlauten übergeben wird, erscheint er Fehlerhaft, zumindest mit OPERA (mit
    MOZILLA ist's O.K.).
    Was stimmt da nicht? Liegt der Fehler etwa am OPERA-Browser? Wie ist es mit
    dem IE?

    Hier ein Beispiel, damit die Sache klarer wird:
    Thumbnail-Link: http://www.postbus.de/cgi-bin/foto.pl?bild=sechura.jpg&titel=in+der+Sechura-Wüste,+Peru&seite=peru.shtml
    Im Opera erscheint nun folgender Bildtitel: in der Sechura-Wüste, Peru

    Nun, die Browser arbeiten alle voellig korrekt. Das, was du bekommst, ist
    lediglich ein UTF-8-String. Stell mal in deinem Browser den Zeichensatz von
    UTF-8 auf ISO-8859-1 oder so, dann sollte es auch gehen. Wenn du in einem
    Formular arbeitest, kannst du natuerlich auch

    accept-charset="ISO-8859-1" angeben. Dann musst du dich darum nicht mehr
    kuemmern.
    Infos bekommst du auf
    http://www.unicode.org/ und
    http://www.cl.cam.ac.uk/~mgk25/unicode.html

    Gruesse,
     CK

    1. MoiN!

      Nun, die Browser arbeiten alle voellig korrekt. Das, was du bekommst, ist
      lediglich ein UTF-8-String. Stell mal in deinem Browser den Zeichensatz von
      UTF-8 auf ISO-8859-1 oder so, dann sollte es auch gehen. Wenn du in einem
      Formular arbeitest, kannst du natuerlich auch
      accept-charset="ISO-8859-1" angeben. Dann musst du dich darum nicht mehr
      kuemmern.

      Ich würde eher dazu tendieren, daß er in der Ausgabeseite den richtigen Zeichensatz angeben sollte.

      Wenn er ein 'ü' als Zeichen überträgt, dann hat das bei UTF-8 und ISO-8859-1 ganz unterschiedliche Bedeutungen.

      Also:
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> ins Dokument eintragen.

      Oder natürlich Umlaute als Entity codieren, das würde auch helfen.

      - Sven Rautenberg

      1. Hoi,

        Oder natürlich Umlaute als Entity codieren, das würde auch helfen.

        Das hat er ja. Da liegt ja das Problem. Wenn der Charset nicht definiert ist,
        gelten Browser-Einstellungen. Und die sind anscheinend im Opera per Default
        UTF-8. Jetzt konvertiert der Opera das im Query-String als ü kodierte
        ü nach UTF-8 und schickt es an das Script. Die Angabe des Charsets im
        Head-Bereich koennte das in der Tat bereinigen, da habe ich gar nicht mal dran
        gedacht.

        Gruesse,
         CK

      2. Nochmal Hallo!
        Die charset=iso-8859-1-Angabe habe ich sowohl in der Ausgangs- als auch in der Ausgabeseite. In der Ausgangsseite wird auch noch alles richtig angezeigt, in der Ausgabeseite wird z.B. "ü" zu "ü". Ein unmaskiertes ü wird richtig dargestellt. Ich dachte nur, Umlaute sollten als "ä", "ö" und "ü" maskiert werden - oder liege ich da falsch?
        Gruß, Mark

        1. MoiN!

          Die charset=iso-8859-1-Angabe habe ich sowohl in der Ausgangs- als auch in der Ausgabeseite. In der Ausgangsseite wird auch noch alles richtig angezeigt, in der Ausgabeseite wird z.B. "ü" zu "ü". Ein unmaskiertes ü wird richtig dargestellt. Ich dachte nur, Umlaute sollten als "ä", "ö" und "ü" maskiert werden - oder liege ich da falsch?

          Nein, nicht unbedingt. Nur mußt du dann natürlich eventuelle Codierungen auch verstehen.

          Es läuft so:
          Der Browser kriegt als Quelltext für den Link folgendes:
          href="/cgi-bin/foto.pl?bild=sechura.jpg&titel=in+der+Sechura-Wüste,+Peru&seite=peru.shtml"

          Das wird durch die Entity-Erkennung konvertiert zu:
          href="/cgi-bin/foto.pl?bild=sechura.jpg&titel=in+der+Sechura-Wüste,+Peru&seite=peru.shtml"

          Und der Umlaut "ü" wird von Opera konvertiert zu "%C3%BC". Sieht ziemlich nach UTF-8-Zeichen aus, zumindest sind es _zwei_ Bytes, wo EIN Byte gereicht hätte. :)

          Tja, und dein Script ist dann einfach nicht in der Lage, aus dieser eindeutigen Definition des Zeichens wieder ein korrektes ü zu machen.

          Und es ist auch nicht in der Lage, das codierte Entity für ü durchzureichen. Wenn ich nämlich
          href="/cgi-bin/foto.pl?bild=sechura.jpg&titel=in+der+Sechura-W%26uuml;ste,+Peru&seite=peru.shtml"
          versuche, dann ist %26 ein &, entsprechend kommt %26uuml; als ü beim Script an, aber irgendwas scheint das Script zu stoppen.

          Guter Rat: Benutze Standardkomponenten für das Entgegennehmen von Formulardaten. Scheinbar ist da was selbstgestricktes am Werkeln. Ich bin nicht der Perl-Modul-Experte, aber irgendwas für CGI gibts garantiert. Sicherlich wird Christian deswegen auch noch in die Bresche springen. :)

          - Sven Rautenberg

  3. Noch mal Hallo! Ich komme der Sache allmählich näher, danke an Euch Antworter!
    Es ligt wohl am Script. Jetzt komme ich aber wieder nicht weiter.
    Das Script sieht so aus:

    #!/usr/bin/perl
    $Method = $ENV{'REQUEST_METHOD'};
    if ($Method eq 'GET') {
            $Query = $ENV{'QUERY_STRING'};
    }
    else {
            read(STDIN,$Query,$ENV{'CONTENT_LENGTH'});
    }

    foreach (split(/[&;]/, $Query)) {           # hier liegt wohl
            s/+/ /g;                           # irgendwo der Fehler!
            ($key, $value) = split('=', $_);
            $key =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
            $value =~ s/%([A-Fa-f0-9]{2})/pack("c",hex($1))/ge;
            $Data{$key} = $value;
    }

    open(FOTO,"foto.html") or Error("Fehler: foto.html kann nicht geöffnet werden", $!);
      while (<FOTO>) {
      next if (/^#/);
      s/%bild%/$Data{bild}/g;
      s/%titel%/$Data{titel}/g;
      s/%seite%/$Data{seite}/g;
      $Text .= "$_";
      }
    close(FOTO);

    print "Content-type: text/html\n\n";
    print "$Text\n";

    1. MoiN!

      foreach (split(/[&;]/, $Query)) {           # hier liegt wohl
              s/+/ /g;                           # irgendwo der Fehler!

      Würde ich auch sagen. Warum splittest du denn den Query-String an & und ;? Trennzeichen ist ausschließlich ein &, kein ;.

      split (/&/, $Query))
      sollte helfen, daß du Entities in den Link packen kannst. Ob du dann immer noch Probleme mit UTF-8 hast, kann dann zweitrangig sein, weil du gültige HTML-Entities in die Ausgabe schleusen kannst.

      - Sven Rautenberg

      1. Hallo,

        foreach (split(/[&;]/, $Query)) {           # hier liegt wohl
                s/+/ /g;                           # irgendwo der Fehler!

        Würde ich auch sagen. Warum splittest du denn den Query-String an & und ;?
        Trennzeichen ist ausschließlich ein &, kein ;.

        Das ist leider falsch. Auch das ';' kann ein Trennzeichen fuer Felder sein. In
        der Spec steht, entweder ';' oder '&'.

        Ansonsten wuerde ich aber eher CGI.pm benutzen.

        Gruesse,
         CK

        1. MoiN!

          Das ist leider falsch. Auch das ';' kann ein Trennzeichen fuer Felder sein. In
          der Spec steht, entweder ';' oder '&'.

          Mist. Also muß das Semikolon auch mit %irgendwas codiert werden.

          Ansonsten wuerde ich aber eher CGI.pm benutzen.

          Eben...

          - Sven Rautenberg

          1. Hoi,

            Das ist leider falsch. Auch das ';' kann ein Trennzeichen fuer Felder sein. In
            der Spec steht, entweder ';' oder '&'.

            Mist. Also muß das Semikolon auch mit %irgendwas codiert werden.

            Richtig. Generell steht in der RFC, nur ASCII-Zeichen mit dem
            Code >= 48 <= 122, '-', '_', '.', '!', '~', '*', "'", '(', ')' brauchen *nicht*
            maskiert werden. ' ' wird mit '+' maskiert, der Rest mit %<Zeichencode in Hex>.
            Dabei ist es allerdings nicht falsch, ' ' mit '%20' zu maskieren.

            Ansonsten wuerde ich aber eher CGI.pm benutzen.

            Eben...

            URI::Escape bietet Funktionen, einen Query-String richtig zu escapen.

            Nachlesen kann man das alles in den RFCs 2396 und 2732.

            Gruesse,
             CK

            1. Hallo!

              Ansonsten wuerde ich aber eher CGI.pm benutzen.
              Eben...
              URI::Escape bietet Funktionen, einen Query-String richtig zu escapen.

              ...hm, sagt mir jetzt alles recht wenig, bin kein so großer Perl-Durchblicker.

              Nachlesen kann man das alles in den RFCs 2396 und 2732.

              Was sind die RFCs 2396 und 2732?

              Mark *???*

              1. Hoi,

                Ansonsten wuerde ich aber eher CGI.pm benutzen.
                Eben...
                URI::Escape bietet Funktionen, einen Query-String richtig zu escapen.
                ...hm, sagt mir jetzt alles recht wenig, bin kein so großer Perl-Durchblicker.

                http://search.cpan.org/search?dist=libwww-perl
                http://search.cpan.org/search?dist=URI

                Nachlesen kann man das alles in den RFCs 2396 und 2732.
                Was sind die RFCs 2396 und 2732?

                RFC steht fuer 'Request For Comment' und sie legen Internet-Standards (na gut,
                nicht *nur* Internet-Standards ;-) fest. Zu finden sind sie z. B. auf

                http://www.rfc-editor.org/

                Gruesse,
                 CK