Charset UTF-8 Problem
mixmastertobsi
- php
Hallo,
ich bin bald am verzweifeln - ich versuche vergeblich meinen Server korrekt einzustellen, damit er mit dem Zeichensatz zurecht kommt.
Zuerst hatte ich das Problem, dass beim AJAX die Antwort fehlerhaft übermittelt wurde. Alle Umlaute etc. wurden nicht korrekt dargestellt. Daraufhin habe ich versucht den Server auf UTF-8 umzustellen. In der PHP.ini habe ich den default_charset = "utf-8" gesetzt.
Leider brachte dies auch nicht den erhofften erfolg. Viel schlimmer - nun wurden nicht nur bei AJAX Antworten die Umlaute falsch übermittelt, sonder auch bei normeln html/php files falsch dargestellt.
Anschließend habe ich in PHP.ini den default-charset = "ISO-8859-1" gesetzt. Nun werden wenigstens alle Umlaute korrekt angezeigt - bis auf das € zeichen im Internetexplorer.
Wie mache ich es denn am besten?!?
Hi!
ich versuche vergeblich meinen Server korrekt einzustellen, damit er mit dem Zeichensatz zurecht kommt.
Zeichenkodierung, aber egal.
Zuerst hatte ich das Problem, dass beim AJAX die Antwort fehlerhaft übermittelt wurde. Alle Umlaute etc. wurden nicht korrekt dargestellt.
Da müssen wir wohl bei den Grundlagen anfangen. In den HTTP-Headers steht eine wichtige Zeile: Content-Type. Die hat für Textdokument einen Parameter namens charset. Wenn der nicht gesetzt ist, darf der Browser ein gleichnamiges Meta-Element verwenden. Bei einer AJAX-Antwort wird oft nur ein Teil vom Dokument, oder anderer Text ohne Möglichkeit der charset-Angabe geliefert. Deshalb ist der genannte HTTP-Header wichtig, um dem Browser nicht das Raten zu überlassen. Und natürlich darfst du bei charset nicht einfach nach Gutdünken was reinschreiben, es muss vielmehr mit der tatsächlich verwendeten Kodierung übereinstimmen.
Daraufhin habe ich versucht den Server auf UTF-8 umzustellen. In der PHP.ini habe ich den default_charset = "utf-8" gesetzt.
Leider brachte dies auch nicht den erhofften erfolg. Viel schlimmer - nun wurden nicht nur bei AJAX Antworten die Umlaute falsch übermittelt, sonder auch bei normeln html/php files falsch dargestellt.
Ja, auf einen Briefumschlag etwas draufschreiben, konvertiert keinen Inhalt. default_charset setzt die oben erwähnte charset-Angabe. Man kann auch im Script einen Header inklusive charset mittels header() festlegen, denn nicht immer kann man die php.ini ändern.
Anschließend habe ich in PHP.ini den default-charset = "ISO-8859-1" gesetzt. Nun werden wenigstens alle Umlaute korrekt angezeigt - bis auf das € zeichen im Internetexplorer.
Das €-Zeichen ist in ISO-8859-1 nicht enthalten. Wenn du es als 0x80 kodierst, so wie es in Windows-1252 definiert ist, dann sollten die Browser eigentlich so gnädig sein, dir diesen Fehler zu verzeihen. Ansonsten hast du nicht die richtig Kodierung erwischt.
Wie mache ich es denn am besten?!?
Gib die Kodierung an, die du tatsächlich verwendest. Sorge dafür, dass dir stets klar ist, welche Kodierung vorliegt. Konkret betrifft das Übergänge zwischen zwei Systemen. Wenn die nicht für den konkreten Datenverkehr wissen, was da kommt, nehmen sie irgendeinen Defaultwert an oder raten irgendwas zusammen. Wenn Kodierungsangabe und Kodierung nicht übereinstimmen, gibt es Interpretationsfehler.
Lo!
Mahlzeit mixmastertobsi,
Leider brachte dies auch nicht den erhofften erfolg. Viel schlimmer - nun wurden nicht nur bei AJAX Antworten die Umlaute falsch übermittelt, sonder auch bei normeln html/php files falsch dargestellt.
Naja, wenn die Dateien selbst nicht in UTF-8 vorliegen, ist das auch kein Wunder ...
Wie mache ich es denn am besten?!?
Am besten richtig. Suche im Archiv nach den Stichworten "Zeichenkodierung" und "Gunnar Bittersmann" - da solltest Du genügend Postings finden, die Dich auf den richtigen Weg schubsen.
MfG,
EKKi
@@EKKi:
nuqneH
Am besten richtig. Suche im Archiv nach den Stichworten "Zeichenkodierung" und "Gunnar Bittersmann" - da solltest Du genügend Postings finden, die Dich auf den richtigen Weg schubsen.
Danke für die Blumen. ;-)
Bei der Suche sollte aber beachtet werden, dass ich "Zeichencodierung" mit C schreibe, damit auch ein paar Treffer kommmen.
Die von mir übersetzten W3C-I18n-Artikel sind auch auf meiner Website zu finden.
Qapla'
Mahlzeit Gunnar Bittersmann,
Danke für die Blumen. ;-)
Gern geschehen - Koniferen sollte man hegen und pflegen ... ;-)
Die von mir übersetzten W3C-I18n-Artikel sind auch auf meiner Website zu finden.
Ha - gewünschter Effekt ist eingetreten: Du hast den Thread bemerkt, Dich eingeklinkt und direkt brauchbare Links gepostet ... und mir damit die Suche nach ebendiesen erspart. :-)
MfG,
EKKi
h1,
ich bin bald am verzweifeln
keep cool ;-)
Prüfe die Zeichencodierung an 3 Stellen
1. Datenquelle (Datei, MySQL, STDIN...)
2. Übertragung (HTTP...)
3. Darstellung (Browser, Notepad...)
Wenn in der Datenquelle (1) die Zeichen utf8-codiert sind und der Browser (3) per HTTP-Header angwiesen wurde, dieselbe Codierung zu verwenden, werden die auch richtig dargestellt.
Die Übertragung (2) hat hinsichtlich Character-Encodung transparent zu sein, wenn das nicht der Fall ist, ändere das.
Näheres auf meiner Website,
Hotti
Hi!
Wenn in der Datenquelle (1) die Zeichen utf8-codiert sind und der Browser (3) per HTTP-Header angwiesen wurde, dieselbe Codierung zu verwenden, werden die auch richtig dargestellt.
Du übergehst, dass zwischen Datenquelle und Browser in der Regel noch ein Programm sitz und damit mindestens drei Systeme und zwei Schnittstellen insgesamt existieren. Zwischen alle Beteiligten muss die zu verwendende Kodierung klar sein, wenn sie die Daten nicht nur durchreichen sondern auch interpretieren und verarbeiten sollen.
Die Übertragung (2) hat hinsichtlich Character-Encodung transparent zu sein, wenn das nicht der Fall ist, ändere das.
Was auch immer du mit "die Übertragung" konkret meinst, es ist nicht zwingend eine Transparenz nötig. Man braucht sie, wenn ein System nur Durchreicher und kein Verarbeiter ist. Ein Verarbeiter muss die Kodierung kennen, damit er die Daten definiert interpretieren kann. Und sei es auch nur, dass die Art, wie eine Kodierungsinformation übergeben wird, zwischen der Quelle und dem Ziel umformuliert werden muss. Eine Datenbank spricht nicht in HTTP-Headern. Der Webserver (oder ein darauf laufendes Programm) muss jedoch einen solchen dem Browser übergeben, weswegen er das Wissen um die Kodierung benötigt.
Lo!
hi mein Guter,
Du übergehst,
Nein, ich erkläre und gebe mir Mühe, das verständlich rüberzubringen. Wahrscheinlich überladen die PHP Entwickler ihre Funktionen dermaßen mit Pragmas, dass am Ende gar keiner mehr durchblickt.
Also, was heißt Transparenz:
=cut
Transparent Mode und Ajax-Response
Wie bereits dargelegt, ist ein Header Content-Type: text/plain; charset=UTF-8 für den Browser verbindlich, also kein Pragma. Im Fall einer Ajax-Response jedoch, kann die charset-Angabe im Header durchaus als Pragma (unverbindlich) betrachtet werden, wenn eine transparente Übertragung sicherstellt, dass die Codierung der Zeichen nicht verändert wird. Betrachte untenstehendes Beispiel zur Übertragung des Zeichens 'ä' welches utf8-codiert sei:
Fall 1: Das Zeichen wird als 'ä' übertragen, hier muss die Codierung im Ajax-Response-Header mitgegeben werden. Ein Header Content-Type: text/plain; charset=UTF-8 ist somit verbindlich.
Fall 2: Das Zeichen 'ä' wird serverseitig als %C3%A4 encodet in die Ajax-Response gegeben. In diesem Fall ist die charset-Angabe im HTTP-Header der Ajax-Response unverbindlich, also nur noch ein Pragma.
Erläuterung: Das Encoding im Fall 2 heißt URI-Escape, damit wird die Übertragung in den transparent mode geschaltet. Die Charset-Angabe im HTTP-Header kann in diesem Fall entfallen oder anders lauten. Transparent mode heißt technisch gesehen: Die Übertragung findet in einer 8-Bit-Umgebung statt, alle zu übertragenden Zeichen sind so encodet, dass im gesamten Content nur noch Zeichen sind, die 7 Bit benötigen (US-ASCII). Feilich muss in einem solchen Fall das URI-Escape im DOM wieder rückgängig gemacht werden, dazu gibt es die Funktionen decodeURI() und decodeURIComponent().
URI-Escape ist keineswegs nur eine Spielerei. Für die Übertragung multipler Contents nach dem MIME-Standard in einer Ajax-Response ist der transparent mode, sichergestellt mit URI-Escape, von größter Bedeutung.
=cut
Ab sofort auf der verlinkten Seite nachzulesen, Du bist schuld ;-)
Hotti
Hi!
Im Fall einer Ajax-Response jedoch, kann die charset-Angabe im Header durchaus als Pragma (unverbindlich) betrachtet werden, wenn eine transparente Übertragung sicherstellt, dass die Codierung der Zeichen nicht verändert wird.
Nur wenn man sich darauf verlässt, dass das Ziel schon alles so wie vorgestellt machen wird, kann man auf konkrete und verbindliche Angaben verzichten.
Fall 1: Das Zeichen wird als 'ä' übertragen, hier muss die Codierung im Ajax-Response-Header mitgegeben werden. Ein Header Content-Type: text/plain; charset=UTF-8 ist somit verbindlich.
Einfach und verbindlich für beide Seiten.
Fall 2: Das Zeichen 'ä' wird serverseitig als %C3%A4 encodet in die Ajax-Response gegeben. In diesem Fall ist die charset-Angabe im HTTP-Header der Ajax-Response unverbindlich, also nur noch ein Pragma.
Das kann ich nicht so sehen. Die charset-Angabe ist weiterhin verbindlich, denn auch %, C, 3, A und 4 werden durch bestimmte Bytes repräsentiert, die es richtig zu interpretieren gilt. Sie ist nur dann egal, wenn man Kodierungen verwendet, die im ASCII-Bereich gleich arbeiten. Das machen aber nicht alle (asiatischen) Kodiersysteme so. Sie verwenden teilweise die Bytes von x00 bis x7F anders oder in Kombination mit anderen Bytes, um andere Zeichen zu repräsentieren. Dein Ignorieren der charset-Angabe funktioniert nur im westlichen Kulturkreis problemlos. Die Ausnahmen mögen für deine Anwendungsfälle nicht relevant sein, zeigen jedoch einen prinzipiellen Fehler bei dieser Vorgehensweise.
Und warum willst du überhaupt in dem Fall URL-kodierte Daten senden? Weil du keine Lust hast, die Zeichenkodierung korrekt zu verwenden und anzugeben? Du nimmst lieber den Umweg und die damit verbundene erhöhte Komplexität in Kauf, noch eine Kodierung obendrauf zu setzen.
Erläuterung: Das Encoding im Fall 2 heißt URI-Escape, damit wird die Übertragung in den transparent mode geschaltet.
Damit schaltest du nichts, damit begibst du dich nur, wie gesagt, auf einen unnötigen Umweg.
Die Charset-Angabe im HTTP-Header kann in diesem Fall entfallen oder anders lauten.
Beliebig darf sie schon gar nicht sein und wenn du sie weglässt, verlässt du dich auf eine Default-Konfiguration des Browsers oder ein richtiges Raten seinerseits.
Transparent mode heißt technisch gesehen: Die Übertragung findet in einer 8-Bit-Umgebung statt, alle zu übertragenden Zeichen sind so encodet, dass im gesamten Content nur noch Zeichen sind, die 7 Bit benötigen (US-ASCII). Feilich muss in einem solchen Fall das URI-Escape im DOM wieder rückgängig gemacht werden, dazu gibt es die Funktionen decodeURI() und decodeURIComponent().
Umständlich und trotzdem nicht richtig, zeigt nur zufällig das gewünschte Verhalten.
URI-Escape ist keineswegs nur eine Spielerei.
Wenn man sie an der richtigen Stelle verwendet. Natürlich kann man sie auch an anderen, ursprünglich nicht vorgesehenden Stellen verwenden und wird bei richtiger Anwendung ein gewünschtes Ergebnis erzielen. Die Frage ist nur, ob das wirklich notwendig ist?
Für die Übertragung multipler Contents nach dem MIME-Standard in einer Ajax-Response ist der transparent mode, sichergestellt mit URI-Escape, von größter Bedeutung.
Achwas. Man kann es auch einfacher richtig machen.
Ab sofort auf der verlinkten Seite nachzulesen, Du bist schuld ;-)
Danke, lieber nicht.
Lo!