fackel: Element IMG: UTF-8-Sonderzeichen in der URI

Hallo zusammen!

Bin völlig verwirrt, wie man das mit den URIs im Attribut SRC beim Element IMG richtig macht. Der Fall: Auf der Platte liegt eine Bilddatei "bläd.jpg" und diese möchte ich in meinem HTML anzeigen. Das HTML wird direkt im Browser geöffnet, geht also erstmal nicht über einen HTTP-Server.

Folgendes hab ich probiert, kann aber die Ergebnisse nicht verstehen (das HTML-Dokument selbst hat als Kodierung UTF-8 - in den METAs angegeben -, und im Text werden Sonderzeichen richtig angezeigt):

(1) Umlaut in UTF-8-Kodierung und escaped (nach meinem Verständnis des RFCs zu URIs und des HTML-Standards sollte das so sein) - Bild wird aber NICHT angezeigt!
<img src="bl%C3%A4d.jpg">

(2) Umlaut als UTF-8, kein Escaping (nach dem Buchstaben des Gesetzes ist das eigentlich falsch, weil eine URI nur ASCII-Zeichen enthalten soll) - Bild wird aber trotzdem angezeigt!
<img src="bläd.jpg" alt="-NOT FOUND-" width="340">

(3) Umlaut in ISO-8859-1-Kodierung und escaped - Bild wird angezeigt (obwohl das Dokument selbst in UTF-8 kodiert ist)
<img src="bl%E4d.jpg">

Warum geht 2, aber nicht 1, obwohl doch beides UTF-8 darstellt und auch der im HTML angegebenen Kodierung entspricht?

Warum geht 3 überhaupt? Das HTML ist doch UTF-8! Wieso kann Firefox die URI richtig auflösen, obwohl die Zeichen "falsch" (also ANSI) kodiert sind?

Kann mich jemand aufklären? Danke.

FF

PS: IE und Firefox sind sich beide einig, was obiges Verhalten betrifft.

  1. hi,

    (2) Umlaut als UTF-8, kein Escaping (nach dem Buchstaben des Gesetzes ist das eigentlich falsch, weil eine URI nur ASCII-Zeichen enthalten soll) - Bild wird aber trotzdem angezeigt!
    <img src="bläd.jpg" alt="-NOT FOUND-" width="340">

    Warum geht 2, aber nicht 1, obwohl doch beides UTF-8 darstellt und auch der im HTML angegebenen Kodierung entspricht?

    Dein Browser ist wohl deiner Meinung, dass das nur ASCII hingehört - also wandelt er das UTF-8 kodierte Zeichen in ASCII, und URL-encoded es dann, weil du's ja offensichtlich "vergessen" hast :-)

    (3) Umlaut in ISO-8859-1-Kodierung und escaped - Bild wird angezeigt (obwohl das Dokument selbst in UTF-8 kodiert ist)
    <img src="bl%E4d.jpg">

    Warum geht 3 überhaupt? Das HTML ist doch UTF-8!

    Das interessiert doch aber den Server nicht.

    Der ASCII-Wert des Zeichens wurde URL-gerecht kodiert, und diese kodierte Darstelung enthält nur die Zeichen %, E und 4. Die sind aber auch in UTF-8 identisch mit der Darstellung in ASCII.

    gruß,
    wahsaga

    --
    /voodoo.css:
    #GeorgeWBush { position:absolute; bottom:-6ft; }
    1. (2) Umlaut als UTF-8, kein Escaping (nach dem Buchstaben des Gesetzes ist das eigentlich falsch, weil eine URI nur ASCII-Zeichen enthalten soll) - Bild wird aber trotzdem angezeigt!
      <img src="bläd.jpg" alt="-NOT FOUND-" width="340">

      Warum geht 2, aber nicht 1, obwohl doch beides UTF-8 darstellt und auch der im HTML angegebenen Kodierung entspricht?

      Dein Browser ist wohl deiner Meinung, dass das nur ASCII hingehört - also wandelt er das UTF-8 kodierte Zeichen in ASCII, und URL-encoded es dann, weil du's ja offensichtlich "vergessen" hast :-)

      Wie soll das UTF-8 kodierte Zeichen in ASCII umgewandelt werden? ASCII hat keine Möglichkeit, mein "ä" zu fassen. Das URL-encoden (das ich in Fall 2 absichtlich "vergessen" habe) - wenn das der Browser intern denn machen würde - würde aber zur Darstellung von Fall 1 führen. Und wie dort festgestellt, wird das Bild (in Fall 1) NICHT angezeigt. Im Gegensatz dazu sehe ich aber in Fall 2 das Bild.

      (3) Umlaut in ISO-8859-1-Kodierung und escaped - Bild wird angezeigt (obwohl das Dokument selbst in UTF-8 kodiert ist)
      <img src="bl%E4d.jpg">

      Warum geht 3 überhaupt? Das HTML ist doch UTF-8!

      Das interessiert doch aber den Server nicht.

      Da ist kein Server im Spiel. Ich stecke das HTML direkt in den Firefox.

      Und selbst wenn ein Server im Spiel wäre: Er kann doch die URIs nicht mach gutdünken interpretieren, sondern sollte sich doch an das Encoding des Dokumentes halten, das er übergeben bekommt. Es könnte doch sein, dass ein und die selbe Darstellung in der URL zu verschiedenen echten Dateinamen im Dateisystem führt, je nachdem welche Kodierung angewendet wird (das trifft insbesondere bei 1-Byte-Kodierungen zu: z.B. ist %E4 in der Kodierung ISO-8859-1 ein "ä", in der Kodierung ISO-8859-5 (kyrillisch) ein "д", und das macht schon einen Unterschied, ob die Datei "bläd.jpg" oder "blдd.jpg" heißt, insbesondere wenn es beide Dateien gleichzeitig gibt).

      Der ASCII-Wert des Zeichens wurde URL-gerecht kodiert, und diese kodierte Darstelung enthält nur die Zeichen %, E und 4. Die sind aber auch in UTF-8 identisch mit der Darstellung in ASCII.

      gruß,
      wahsaga

      Dank für die Antwort. Leider ist meine Verwirrung damit noch nicht beseitigt. Vielleicht hab ich deine Antworten aber auch missverstanden.

      Nur zur Klarstellung:

      a) Die Varianten 2 und 3 hab ich mir "ausgedacht", nachdem die in meinen Augen saubere Variante 1 nicht funktioniert.

      b) Es ist kein Server zwischengeschaltet, der die URIs evtl. hinbiegt oder "besser" auflösen kann.

      c) Was will ich #1: Ich suche nach einem Weg, Sonderzeichen in SRC in IMG zu verwenden, so dass HTML-Browser zuverlässig damit umgehen können.

      d) Was will ich #2: Ich würde gerne verstehen, warum Firefox (und mit ihm IE) sich so verhalten, wie sie sich verhalten.

      FF

      1. hi,

        Wie soll das UTF-8 kodierte Zeichen in ASCII umgewandelt werden? ASCII hat keine Möglichkeit, mein "ä" zu fassen.

        Gut, nicht ASCII - vielleicht eher ISO-8859-1.

        Das interessiert doch aber den Server nicht.

        Da ist kein Server im Spiel. Ich stecke das HTML direkt in den Firefox.

        An wen geht denn die Anfrage nach der Ressource?

        Und selbst wenn ein Server im Spiel wäre: Er kann doch die URIs nicht mach gutdünken interpretieren, sondern sollte sich doch an das Encoding des Dokumentes halten, das er übergeben bekommt.

        Der Server bekommt doch kein Dokument übergeben, sondern nur einen Request nach einer Ressource.

        Es könnte doch sein, dass ein und die selbe Darstellung in der URL zu verschiedenen echten Dateinamen im Dateisystem führt, je nachdem welche Kodierung angewendet wird (das trifft insbesondere bei 1-Byte-Kodierungen zu: z.B. ist %E4 in der Kodierung ISO-8859-1 ein "ä", in der Kodierung ISO-8859-5 (kyrillisch) ein "д", und das macht schon einen Unterschied, ob die Datei "bläd.jpg" oder "blдd.jpg" heißt, insbesondere wenn es beide Dateien gleichzeitig gibt).

        Ein und der selbe URL kann nicht zu verschiedenen Ressourcen führen.

        Und wenn der Server den Request bekommt, weiß er nichts von irgendwelchen vorher auf dem Client eventuell mal angezeigten Dokumenten, die in irgendeiner Kodierung vorlagen.

        b) Es ist kein Server zwischengeschaltet, der die URIs evtl. hinbiegt oder "besser" auflösen kann.

        Von wo forderst du die Ressourcen dann an?
        Lädst du lediglich Dateien aus dem lokalen Dateisystem des Clientrechners?

        c) Was will ich #1: Ich suche nach einem Weg, Sonderzeichen in SRC in IMG zu verwenden, so dass HTML-Browser zuverlässig damit umgehen können.

        Am besten verwendest du sie gar nicht.

        Und wenn doch - dann musst du natürlich die Kodierung verwenden, die im Dateisystem (lokal oder des Servers) für die Dateinamen benutzt wird - und die Darstellung des Dateinamens in dieser Kodierung URL-gerecht kodieren.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }
        1. Hallo,

          Das interessiert doch aber den Server nicht.

          Da ist kein Server im Spiel. Ich stecke das HTML direkt in den Firefox.

          An wen geht denn die Anfrage nach der Ressource?

          An das lokale Dateisystem. Das Szenario ist hier wirklich lokales Öffnen der HTML-Datei im Browser.

          Und selbst wenn ein Server im Spiel wäre: Er kann doch die URIs nicht mach gutdünken interpretieren, sondern sollte sich doch an das Encoding des Dokumentes halten, das er übergeben bekommt.

          Der Server bekommt doch kein Dokument übergeben, sondern nur einen Request nach einer Ressource.

          Die Ressource muss aber als URL spezifiziert sein, und diese URL muss ja die Sonderzeichen in irgend einer Kodierung darstellen. Woher weiß also der Server, in welcher Kodierung das sein soll, was da ankommt?

          Es könnte doch sein, dass ein und die selbe Darstellung in der URL zu verschiedenen echten Dateinamen im Dateisystem führt, je nachdem welche Kodierung angewendet wird (das trifft insbesondere bei 1-Byte-Kodierungen zu: z.B. ist %E4 in der Kodierung ISO-8859-1 ein "ä", in der Kodierung ISO-8859-5 (kyrillisch) ein "д", und das macht schon einen Unterschied, ob die Datei "bläd.jpg" oder "blдd.jpg" heißt, insbesondere wenn es beide Dateien gleichzeitig gibt).

          Ein und der selbe URL kann nicht zu verschiedenen Ressourcen führen.

          Ich denke doch, wenn die Kodierung der URL (etwa bl%E4d.jpg) implizit angenommen und nicht irgendwie explizit festgelegt wird. Und explizit festgelegt kann sie doch nur durch das umgebende Dokument werden, d.h. bzw. der Browser müsste beim Anfordern einer Ressource dem Server mitteilen, in welcher Kodierung die URL ist. Gibt es soetwas überhaupt? Über Einzelheiten des HTTP-Protokolls oder das ganze Server-Gedöns weiß ich zu wenig.

          Und wenn der Server den Request bekommt, weiß er nichts von irgendwelchen vorher auf dem Client eventuell mal angezeigten Dokumenten, die in irgendeiner Kodierung vorlagen.

          b) Es ist kein Server zwischengeschaltet, der die URIs evtl. hinbiegt oder "besser" auflösen kann.

          Von wo forderst du die Ressourcen dann an?
          Lädst du lediglich Dateien aus dem lokalen Dateisystem des Clientrechners?

          Jap.

          c) Was will ich #1: Ich suche nach einem Weg, Sonderzeichen in SRC in IMG zu verwenden, so dass HTML-Browser zuverlässig damit umgehen können.

          Am besten verwendest du sie gar nicht.

          Beim aktuellen Erkenntnisstand zum Thema URLs & Kodierung würde ich das sehr gerne. Die Option hab ich als Entwickler aber leider nicht, weil die Autoren der (XML-)Dokumente, aus denen das HTML entstehen soll, die Dateinamen für Bilder eben manchmal mit Umlauten/Sonderzeichen spicken.

          Und wenn doch - dann musst du natürlich die Kodierung verwenden, die im Dateisystem (lokal oder des Servers) für die Dateinamen benutzt wird - und die Darstellung des Dateinamens in dieser Kodierung URL-gerecht kodieren.

          Das ist leider auch problematisch, weil ich es leider wiederum nicht im Griff habe, wo dieses HTML zur Anzeige kommt: hier in Europa oder in Fernost, oder auf CD.

          Danke für die Infos,
          FF

      2. Hallo,

        Da ist kein Server im Spiel. Ich stecke das HTML direkt in den Firefox.

        Doch ist ein Server im Spiel. Für das file-Protokoll ist das Betriebssystem und dessen Dateisystem zuständig. Das weiß wohl nichts von UTF-8.

        a) Die Varianten 2 und 3 hab ich mir "ausgedacht", nachdem die in meinen Augen saubere Variante 1 nicht funktioniert.

        Bei mir, mit Apache2 unter Windows, funktionieren in einem mit
        Content-Type: text/html; charset=UTF-8
        ausgelieferten Dokument folgende Links:

        <a href="bläd.html">bl&auml;d</a>
        <a href="bl%C3%A4d.html">bl&auml;d</a>
        <a href="bl&auml;d.html">bl&auml;d</a>

        Beim Server kommt dabei jeweils:

        GET /bl%C3%A4d.html HTTP/1.1

        an und wird korrekt als im Dateisystem gespeicherte bläd.html ausgeliefert. Ich würde

        <a href="bl&auml;d.html">bl&auml;d</a>

        favorisieren, weil das am neutralsten ist. Das funktioniert übrigens auch im Dateisystem.

        b) Es ist kein Server zwischengeschaltet, der die URIs evtl. hinbiegt oder "besser" auflösen kann.

        Doch, aber eben einer, der mit UTF-8 nicht umgehen kann.

        c) Was will ich #1: Ich suche nach einem Weg, Sonderzeichen in SRC in IMG zu verwenden, so dass HTML-Browser zuverlässig damit umgehen können.

        Wenn das 100%-ig der Fall sein soll, dann verwende keine nicht-ASCII-Sonderzeichen in Ressourcenbezeichnern. Wenn doch, bist Du immer vom Verhalten der Browser und der ausliefernden Server abhängig und das kann durchaus nervig sein.

        d) Was will ich #2: Ich würde gerne verstehen, warum Firefox (und mit ihm IE) sich so verhalten, wie sie sich verhalten.

        Nicht die Browser, sondern das Dateisystem Deines Betriebssystems.

        viele Grüße

        Axel

        1. Hallo,

          Ich würde

          <a href="bl&auml;d.html">bl&auml;d</a>

          favorisieren, weil das am neutralsten ist.

          »bläd.html« ist keine gültige URI, wie der OP schon im Ausgangsposting bemerkte.

          Mathias

          --
          »No nations, no borders.«
          Visitenkarte · SELFHTML Weblog
          1. Hallo,

            »bläd.html« ist keine gültige URI, wie der OP schon im Ausgangsposting bemerkte.

            Isch weiß ;-). Sagte ich, dass man keine nicht-ASCII-Zeichen in Ressoucenbezeichnern verwenden sollte, wenn es 100%-ig funktionieren soll? Denn bl%C3%A4d.html ist ggf. keine Ressource, die der Server korrekt anforden kann.

            viele Grüße

            Axel

        2. Hi,

          Da ist kein Server im Spiel. Ich stecke das HTML direkt in den Firefox.
          Doch ist ein Server im Spiel. Für das file-Protokoll ist das Betriebssystem und dessen Dateisystem zuständig. Das weiß wohl nichts von UTF-8.

          Aus deiner Sicht betrachtet muss das Betriebssystem aber doch etwas von UTF-8 wissen, weil Nummer 2 (die "binäre Darstellung" in UTF-8) ja funktioniert. Heißt das, dass das BS nur das Unescapen der UTF-8-Zeichen nicht hingekriegt hat; hm, aber wieso hat dann bei Latin-1 das Unescapen geklappt?

          Du bezeichnest das Betriebssystem mit dessen Dateisystem als "Server". Dem könnte ich mich problemlos anschließen, wenn es eine native Betriebssystemfunktion gäbe, die URLs in (ja, wie bezeichne ich das) System-Identifier auflöst. Ich würde aber eher (aus meiner Programmierpraxis - sprich, Code anderer Leute lesen, weil ich zu wenig selbst schreibe) vermuten, dass diese Auflösung im Browser (oder weiter unten, in Apache2) programmiert ist, weil das Betriebssystem nativ wohl nur "System-Identifier"  nicht aber URIs/URLs versteht.

          a) Die Varianten 2 und 3 hab ich mir "ausgedacht", nachdem die in meinen Augen saubere Variante 1 nicht funktioniert.
          Bei mir, mit Apache2 unter Windows,

          Wenn ich jetzt ganz tief bohren wollte ;) könnte ich fragen, warum denn der Apache (ist doch letztlich auch nur ein Browser), der ja auf demselben "Server" Betriebssystem sitzt wie mein Firefox, das denn mit genau der URL kann, die über meinen Firefox nicht funktioniert.

          funktionieren in einem mit
          Content-Type: text/html; charset=UTF-8
          ausgelieferten Dokument folgende Links:

          <a href="bläd.html">bl&auml;d</a>
          <a href="bl%C3%A4d.html">bl&auml;d</a>
          <a href="bl&auml;d.html">bl&auml;d</a>

          Beim Server kommt dabei jeweils:

          GET /bl%C3%A4d.html HTTP/1.1

          an und wird korrekt als im Dateisystem gespeicherte bläd.html ausgeliefert.

          So hatte ich mir das auch bei meiner initialen Variante 1 gedacht, bis mir die Browser einen Strich durch die Rechnung machten.

          c) Was will ich #1: Ich suche nach einem Weg, Sonderzeichen in SRC in IMG zu verwenden, so dass HTML-Browser zuverlässig damit umgehen können.
          Wenn das 100%-ig der Fall sein soll, dann verwende keine nicht-ASCII-Sonderzeichen in Ressourcenbezeichnern. Wenn doch, bist Du immer vom Verhalten der Browser und der ausliefernden Server abhängig und das kann durchaus nervig sein.

          Ich (als Entwickler) kann leider die Sonderzeichen in Dateinamen nicht verhindern, muss also damit leben :-( Und wie mir aus der sehr hilfreichen Diskussion scheint, werde ich keine "schöne" Lösung dafür einsetzen können.

          viele Grüße

          Axel

          1. Hallo,

            a) Die Varianten 2 und 3 hab ich mir "ausgedacht", nachdem die in meinen Augen saubere Variante 1 nicht funktioniert.
            Bei mir, mit Apache2 unter Windows,

            Wenn ich jetzt ganz tief bohren wollte ;) könnte ich fragen, warum denn der Apache (ist doch letztlich auch nur ein Browser), der ja auf demselben "Server" Betriebssystem sitzt wie mein Firefox, das denn mit genau der URL kann, die über meinen Firefox nicht funktioniert.

            Die Browser sind in dem Punkt dumm.

            Dein Forschergeist in allen Ehren, aber eine vernünftigere Erklärung wird sich wohl nicht finden lassen.

            Mathias

            --
            »No nations, no borders.«
            Visitenkarte · SELFHTML Weblog
          2. Hallo,

            Aus deiner Sicht betrachtet muss das Betriebssystem aber doch etwas von UTF-8 wissen, weil Nummer 2 (die "binäre Darstellung" in UTF-8) ja funktioniert.

            Ja, weil der Browser nicht bläd anfordert, sondern bläd. Dein Editor speichert offensichtlich kein UTF-8. Dadurch werden die beiden Bytes ä in einem Latin-1 Dokument gespeichert, welches dem Browser dann per charset=UTF-8 als UTF-8 untergeschoben wird. Dieser erzeugt dann aus den _zwei_ Bytes ä das _eine_ Zeichen ä.

            Heißt das, dass das BS nur das Unescapen der UTF-8-Zeichen nicht hingekriegt hat; hm, aber wieso hat dann bei Latin-1 das Unescapen geklappt?

            Nein, es heißt, dass das Betriebssystem nichts mit UTF-8-Dateinamen anfangen kann. Das Unescapen klappt. Es wird in Windows sicherlich durch einen URL-Handler in einer *.dll erledigt.

            Du bezeichnest das Betriebssystem mit dessen Dateisystem als "Server". Dem könnte ich mich problemlos anschließen, wenn es eine native Betriebssystemfunktion gäbe, die URLs in (ja, wie bezeichne ich das) System-Identifier auflöst.

            Das muss es geben, sonst könnte man ja keine URL-Verknüpfungen im Dateisystem erstellen. Das kann man aber.

            a) Die Varianten 2 und 3 hab ich mir "ausgedacht", nachdem die in meinen Augen saubere Variante 1 nicht funktioniert.
            Bei mir, mit Apache2 unter Windows,

            Wenn ich jetzt ganz tief bohren wollte ;) könnte ich fragen, warum denn der Apache (ist doch letztlich auch nur ein Browser),

            Bitte? http://httpd.apache.org/

            der ja auf demselben "Server" Betriebssystem sitzt wie mein Firefox, das denn mit genau der URL kann, die über meinen Firefox nicht funktioniert.

            Er, der HTTP-Server, und nicht mehr das Betriebssystem direkt, liefert die Ressource hinter der URL aus. Er arbeitet dabei mit dem Betriebssystem zusammen, kann das aber offensichtlich so, dass auch UTF-8-Ressourcenbezeichner funktionieren.

            viele Grüße

            Axel