Welche Zeichenkodierung sollte ich für einen HTTP-Header verwenden?

122

Ich verwende ein "lustiges" HTML-Sonderzeichen (✰) (siehe http://html5boilerplate.com/ für weitere Informationen) für einen ServerHTTP-Header und frage mich, ob es pro Spezifikation "erlaubt" ist.

  • Wenn ich die Registerkarte "Netzwerk" in den Entwicklertools in Chrome unter Windows XP Pro SP 3 verwende, sehe ich das ✰ in Ordnung.

  • In IE8 wird das ✰ nicht korrekt gerendert.

  • Der HTML-Validator von w3.org rendert es nicht korrekt (zeigt â°stattdessen " " an).

Jetzt bin ich nicht besonders scharf auf Charaktercodierungen ... und ehrlich gesagt interessieren sie mich nicht wirklich. Ich benutze nur blind UTF-8, weil ich dazu aufgefordert werde. :-)


Wird die Ungleichheit durch Fehler in den verschiedenen Parsern / Browsern / Engines / (wie auch immer sie genannt werden) verursacht?

Gibt es eine Spezifikation dafür oder vielleicht eine Liste zulässiger Zeichen für einen HTTP-Header "Wert"?

David Murdoch
quelle
29
Diese Frage wäre im Allgemeinen viel besser gestellt: "Welche Zeichen sind in einem http-Header-Wert erlaubt"
Akrikos
2
"Jetzt bin ich nicht besonders scharf auf Zeichenkodierungen ... und ehrlich gesagt interessieren sie mich nicht sonderlich. Ich benutze nur blind UTF-8, weil mir gesagt wurde :-)" <--- - Obligatorischer Link zu joelonsoftware.com/2003/10/08/…
d4nyll

Antworten:

124

Kurz gesagt: Nur ASCII funktioniert garantiert. Einige Nicht-ASCII-Bytes sind aus Gründen der Abwärtskompatibilität zulässig, sollten jedoch nicht angezeigt werden können.

HTTPbis gab auf und gab an, dass es in den Headern außer ASCII keine nützliche Codierung gibt:

In der Vergangenheit hat HTTP Feldinhalte mit Text im Zeichensatz ISO-8859-1 [ISO-8859-1] zugelassen, wobei andere Zeichensätze nur mithilfe der Codierung [RFC2047] unterstützt wurden. In der Praxis verwenden die meisten HTTP-Headerfeldwerte nur eine Teilmenge des US-ASCII-Zeichensatzes [USASCII]. Neu definierte Header-Felder sollten ihre Feldwerte auf US-ASCII-Oktette beschränken. Ein Empfänger sollte andere Oktette im Feldinhalt (obs-text) als undurchsichtige Daten behandeln.


Zuvor definierte RFC 2616 von 1999 Folgendes:

Wörter von * TEXT KÖNNEN Zeichen aus anderen Zeichensätzen als ISO-8859-1 [22] nur enthalten, wenn sie gemäß den Regeln von RFC 2047 [14] codiert sind.

und RFC 2047 ist die MIME-Codierung , also wäre es:

=?UTF-8?Q?=E2=9C=B0?=

aber ich denke nicht, dass viele (wenn überhaupt) Kunden dies unterstützen.

Kornel
quelle
7
was bedeutet das? Ist "✰" gültig / erlaubt?
David Murdoch
8
Um eine sehr nützliche Antwort etwas zu erweitern: "UTF-8" ist der Zeichensatz, und "Q" bedeutet, dass der Wert "in Anführungszeichen druckbar" ist. "B" kann auch verwendet werden, wenn Sie den Wert BASE64-codieren möchten.
GargantuChet
1
@porneL, Was bedeutet "undurchsichtige Daten"? Was genau sollte der HTTP-Empfänger tun, wenn er diese "undurchsichtigen Daten" empfängt?
Pacerier
1
@Pacerier "undurchsichtige Daten" bedeutet, dass es sich um eine Black Box mit einer Reihe von Bytes handelt, die Anwendungen nicht anzeigen oder interpretieren sollten (wie Binärdaten). Was damit passiert, hängt vom Header ab und kann von "nichts" bis "verwerfen" reichen.
Kornel
@Kornel, übrigens, warum hast du deinen Benutzernamen in kornel geändert?
Pacerier
10

Bitte lesen Sie zuerst die Kommentare. Diese Antwort zieht wahrscheinlich falsche Schlussfolgerungen aus den richtigen Quellen und muss bearbeitet werden.


Sie können beliebige druckbare ASCII-Zeichen und keine speziellen Zeichen wie ✰ verwenden (was nicht ASCII ist ).

Tipp : Sie können alles in JSON codieren.

Bearbeiten : Möglicherweise zunächst nicht offensichtlich. Die im Header definierte Zeichenkodierung gilt nur für den Antworttext, nicht für den Header selbst. (Als würde es ein Henne-Ei-Problem verursachen.)


Ich möchte die entsprechenden Definitionen alle zusammenzufassen gemäß der Spezifikation durch Penchant verknüpft.

message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )

Wir sind also hinter dem Feldwert her .

LWS            = [CRLF] 1*( SP | HT )
CRLF           = CR LF
CR             = <US-ASCII CR, carriage return (13)>
LF             = <US-ASCII LF, linefeed (10)>
SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>

LWS steht für Linear White Space. Im Wesentlichen ist LWS Leerzeichen oder Tabulator, aber Sie können Ihren Feldwert in mehrere Zeilen aufteilen, indem Sie eine neue Zeile vor einem Leerzeichen oder Tabulator beginnen.

Vereinfachen wir es folgendermaßen:

field-value    = <any field-content or Space or Tab>

Jetzt sind wir nach Feldinhalten .

field-content  = <the OCTETs making up the field-value
                 and consisting of either *TEXT or combinations
                 of token, separators, and quoted-string>
OCTET          = <any 8-bit sequence of data>
TEXT           = <any OCTET except CTLs,
                 but including LWS>
CTL            = <any US-ASCII control character
                 (octets 0 - 31) and DEL (127)>
token          = 1*<any CHAR except CTLs or separators>
separators     = "(" | ")" | "<" | ">" | "@"
                 | "," | ";" | ":" | "\" | <">
                 | "/" | "[" | "]" | "?" | "="
                 | "{" | "}" | SP | HT

TEXT ist der allgemeinste und beinhaltet den ganzen Rest - also vergiss den Rest -. Hier ist der US-ASCII-Zeichensatz (= ASCII)

Wie Sie sehen können, sind alle druckbaren ASCII-Zeichen zulässig.

zupa
quelle
3
Sie widersprechen den von Ihnen zitierten Passagen. Warum sagst du "und keine Sonderzeichen wie ✰"? Sonderzeichen sind nur OCTETs, und da TEXTes keine OCTETAusnahme gibt 0 - 31, bedeutet dies, dass alle OCTETs von 32bis 255 zulässig sind . Die Oktetts ✰ sind 226, 156und 176alle drei von ihnen erlaubt, daher ✰ darf nach den Durchlässen Sie zitiert.
Pacerier
2
@ Pacerier Sie scheinen völlig richtig zu sein, ich verstehe nicht, warum ich die Schlussfolgerung gezogen habe, die ich gemacht habe.
Zupa
@ Pacerier Ich bin noch nicht bereit, es zu bearbeiten, da ich die Spezifikation erneut überprüfen musste. Ich befürchte, dass zusätzliche Details auf den US-ASCII-Zeichensatz beschränkt sind, was wiederum die Schlussfolgerung stützen und die Argumentation unzureichend machen würde.
Zupa
1
Die Aussage "Sie können alles in JSON codieren" ist etwas irreführend. JSON erlaubt Unicode-Zeichen, während HTTP-Header US-ASCII sein sollten. Unicode-Zeichen werden als "undurchsichtige" Daten behandelt, und daher ist das Verhalten in der HTTP-Spezifikation nicht definiert. Abgesehen davon kann JSON für die Aufnahme in einen HTTP-Header sicher gemacht werden, indem die Unicode-Zeichen über die Escape-Sequenz \ uXXXX maskiert werden.
Jacob
@zupa, Ein weiteres Problem ist ... was bedeutet " außerCTLs "? Ist es die Zeichen bedeuten CR, LFsind erlaubt? Oder heißt das, dass nur die fortlaufende Folge " CR LF SP/ HT" erlaubt ist? (Mit anderen Worten kann, Header - Werte ein einzelnes enthalten CRoder LFoder HTCan - Header - Werte enthalten die Zeichen? CR, LFUnd HTin beliebiger Reihenfolge und Menge?)
Pacerier