Dieser Eingabetext enthält oft Zeichen, die für die Ausgabekodierung nicht korrekt sind, wie z. B. "intelligente Anführungszeichen", die aus einem Dokument in Windows-1252-Kodierung stammen
"Intelligente Anführungszeichen" (Bytes 147 und 148 in cp1252) sind vollkommen gültige Unicode-Zeichen, U+201C und U+201D. Ihre Anwendung sollte in der Lage sein, sie nahtlos zu verarbeiten; wenn nicht, machen Sie etwas falsch und höchstwahrscheinlich werden alle Nicht-ASCII-Zeichen fehlschlagen.
Unabhängig davon, ob die Zeichen von jemandem stammen, der sie eintippt, oder von jemandem, der sie aus Word einfügt, sollte der Browser UTF-8-kodierte Zeichen an Ihre Anwendung übermitteln, die die gleichen UTF-8-Bytes in der Datenbank speichern sollte.
Wenn der Browser nicht in UTF-8 sendet, ist es wahrscheinlich, dass Sie den Zeichensatz der HTML-Seite, die das Formular enthält, nicht eingestellt haben. Dies kann mit der Option:
Content-Type: text/html;charset=utf-8
HTTP-Header und/oder die:
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
Element in <head>.
Kann ich einfach das accept-charset-Attribut auf dem Formular setzen und den Browser dies für mich tun lassen?
Nein, accept-charset ist im Grunde nutzlos dank des IE, der es fälschlicherweise so interpretiert, dass es bedeutet "versuche diesen Zeichensatz zu verwenden, wenn der auf der Seite die gewünschten Zeichen nicht kodieren kann", anstatt "verwende immer diesen Zeichensatz". Das bedeutet, wenn Sie accept-charset verwenden, können Sie mit einer Mischung von Kodierungen enden, die auf einmal übermittelt werden, ohne dass Sie herausfinden können, welche die richtige ist. Toll!
Wie kommt es, dass meine Datenbank diese Zeichen akzeptiert, die in UTF-8 reserviert/kontrolliert sind?
In MySQL ist UTF-8 nur eine Sortierreihenfolge, die zum Vergleich und zur Ordnung verwendet wird. Es speichert die Daten immer noch als Bytes und kümmert sich nicht wirklich darum, ob sie keine gültigen UTF-8-Sequenzen sind.
Es ist auf jeden Fall eine gute Idee, eingehende UTF-8-Sequenzen in Ihrer Anwendung zu dekodieren und zu überprüfen, da "kurze Sequenzen", die in modernem Unicode ungültig sind, ein "<"-Zeichen verbergen können, das von älteren Browsern (zumindest IE6 vor SP2, Opera 7) noch erkannt wird.
ETA:
Ich habe also eine Zeichenkette mit Byte 146 eingegeben
Nein, Sie haben ein Unicode-Zeichen U+201B eingegeben. Der Browser arbeitet mit Unicode-Zeichen und nicht mit Bytes, und zwar bis zu dem Punkt, an dem er das serialisierte Formular an den Server übermitteln muss. Erst dann entscheidet er, wie er die Zeichen in Bytes umwandelt, und wenn die Seite als UTF-8 behandelt wird, wählt er immer UTF-8.
(Wenn es sich nicht um UTF-8 handelt, neigen die Browser dazu, auf eine nicht standardkonforme Weise zu schummeln: alle Zeichen, die nicht in die Kodierung passen, werden in HTML-Zeichenreferenzen wie ''' kodiert. Das ist falsch, weil man jetzt nicht mehr zwischen einem vom Browser umcodierten '&' und einem echten, vom Benutzer eingegebenen '&' unterscheiden kann, und es ist heimtückisch falsch, weil es, wenn man den Verweis dann als nicht umcodiertes HTML wiedergibt, so aussieht, als würde man es richtig machen, was in Wirklichkeit nur ein großes altes Sicherheitsloch ist).
Sie wurde in der Datenbank als 146
Wirklich, ein \x92 ' Byte, nicht ' \xC2\x92 ', ' \xE2\x80\x99 ' oder ''?
es kam heraus, als ich die (UTF-8-kodierte) XML-Datei als 146. Keine Beschwerden seitens des Browsers
Dann kam es nicht als ein einziges 146-Byte heraus. Ein Browser wird sich beschweren, wenn er einen bloßen ' \x92 ' in einer XML-Datei. (Nicht in einer HTML-Datei, in der ungültige UTF-8-Sequenzen als fehlende Zeichen angezeigt werden).
Ich vermute, dass es als ''-Zeichenreferenz ausgegeben wird, was wohlgeformt ist (obwohl das Zeichen U+0092 Teil des C1-Steuersatzes ist und daher nicht als etwas Nützliches dargestellt wird). Wenn dies der Fall ist, wird Ihre Formularseite nicht als UTF-8 erkannt, und Sie leiden unter dem oben beschriebenen Problem der automatischen Abschreibung durch den Browser bei der Übermittlung.