Quale codifica dei caratteri dovrei usare per un'intestazione HTTP?


122

Sto usando un carattere speciale HTML "divertente" (✰) (vedi http://html5boilerplate.com/ per maggiori informazioni) per Serverun'intestazione HTTP e mi chiedo se sia "consentito" per specifica.

  • Utilizzando la scheda Rete negli strumenti di sviluppo in Chrome su Windows Xp Pro SP 3 vedo che the va bene.

  • In IE8 il ✰ non è reso correttamente.

  • Il validatore HTML di w3.org non lo visualizza correttamente (visualizza â°invece " ").

Ora, non mi piacciono molto le codifiche dei caratteri ... e francamente non mi interessano molto di loro; Uso ciecamente UTF-8 perché mi è stato detto di farlo. :-)


La disparità è causata da bug nei diversi parser / browser / motori / (come si chiamano)?

Esiste una specifica per questo o forse un elenco di caratteri consentiti per un "valore" di intestazione HTTP?


29
Questa domanda sarebbe molto meglio posta in generale: "Quali caratteri sono consentiti in un valore di intestazione http"
Akrikos


2
"Ora, non mi piacciono molto le codifiche dei caratteri ... e francamente non mi interessano molto di loro; Uso ciecamente UTF-8 perché mi è stato detto di farlo. :-)" <--- - Link obbligatorio a joelonsoftware.com/2003/10/08/…
d4nyll

Risposte:


124

In breve: solo ASCII è garantito per funzionare. Alcuni byte non ASCII sono consentiti per compatibilità con le versioni precedenti, ma non dovrebbero essere visualizzabili.

HTTPbis ha rinunciato e ha specificato che nelle intestazioni non c'è codifica utile oltre ad ASCII:

Storicamente, HTTP ha consentito il contenuto dei campi con testo nel set di caratteri ISO-8859-1 [ISO-8859-1], supportando altri set di caratteri solo attraverso l'uso della codifica [RFC2047]. In pratica, la maggior parte dei valori dei campi di intestazione HTTP utilizza solo un sottoinsieme del set di caratteri US-ASCII [USASCII]. I campi di intestazione appena definiti DOVREBBERO limitare i loro valori di campo agli ottetti US-ASCII. Un destinatario DOVREBBE trattare gli altri ottetti nel contenuto del campo (testo fisso) come dati opachi.


In precedenza, RFC 2616 del 1999 lo definiva:

Parole di * TEXT PU contenere caratteri da set di caratteri diversi da ISO- 8859-1 [22] solo se codificati secondo le regole della RFC 2047 [14].

e RFC 2047 è la codifica MIME , quindi sarebbe:

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

ma non credo che molti (se ce ne sono) client lo supportino.


7
Che cosa vuol dire? "✰" è valido / consentito?
David Murdoch

8
Per espandere un po 'una risposta molto utile: "UTF-8" è il set di caratteri e "Q" significa che il valore sarà "stampabile tra virgolette". "B" potrebbe essere utilizzato anche se si desidera codificare il valore in BASE64.
GargantuChet

1
@ porneL, Allora cosa significa "dati opachi"? Che cosa esattamente deve il destinatario HTTP fare quando riceve questi "opaco dati"?
Pacerier

1
@Pacerier "dati opachi" significa che è una scatola nera con un mucchio di byte che le applicazioni non dovrebbero tentare di visualizzare o interpretare (come i dati binari). Quello che succede con esso dipende dall'intestazione, potrebbe variare da "niente" a "scarta".
Kornel

@Kornel, Btw perché hai cambiato il tuo nome utente in kornel?
Pacerier

10

Si prega di leggere prima i commenti, questa risposta probabilmente trae conclusioni sbagliate dalle fonti giuste, necessita di modifiche.


Puoi usare qualsiasi carattere ASCII stampabile e nessun carattere speciale come ✰ (che non è ASCII )

Suggerimento : puoi codificare qualsiasi cosa in JSON.

Modifica : all'inizio potrebbe non essere ovvio, la codifica dei caratteri definita nell'intestazione si applica solo al corpo della risposta, non all'intestazione stessa. (Poiché causerebbe un problema con uova e gallina.)


Vorrei riassumere tutte le definizioni rilevanti secondo le specifiche collegate da Penchant.

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

Quindi, stiamo cercando valore di campo .

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 è l'acronimo di Linear White Space. Essenzialmente, LWS è spazio o tabulazione, ma puoi suddividere il valore del campo in più righe iniziando una nuova riga prima di uno spazio o di una tabulazione.

Semplifichiamolo in questo modo:

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

Ora stiamo cercando il contenuto del campo .

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

TESTO è il più generale e include tutto il resto, quindi dimentica il resto. Ecco il set di caratteri US-ASCII (= ASCII)

Come puoi vedere, sono consentiti tutti i caratteri ASCII stampabili.


3
Stai contraddicendo i passaggi che hai citato. Perché dici "e nessun carattere speciale come ✰"? I caratteri speciali sono solo OCTETs, e Poiché TEXTè qualsiasi OCTETtranne 0 - 31, significa che sono consentiti tutti OCTETi caratteri da 32a . Gli ottetti di ✰ sono , e e tutti e tre sono consentiti, quindi ✰ è consentito in base ai passaggi che hai citato. 255 226156176
Pacerier

2
@Pacerier mi sembri completamente giusto, non vedo perché ho tratto la conclusione che ho fatto.
zupa

@Pacerier ancora non sono pronto per modificarlo perché dovevo ricontrollare nuovamente le specifiche. Temo che ulteriori dettagli si limitino al set di caratteri US-ASCII che a sua volta sosterrebbe la conclusione ma renderebbe il ragionamento insufficiente.
zupa

1
Dire "puoi codificare qualsiasi cosa in JSON" è un po 'fuorviante. JSON consente i caratteri Unicode, mentre le intestazioni HTTP dovrebbero essere US-ASCII. I caratteri Unicode verranno trattati come dati "opachi" e quindi il comportamento non è definito dalla specifica HTTP. Detto questo, JSON può essere reso sicuro per l'inclusione in un'intestazione HTTP eseguendo l'escape dei caratteri Unicode tramite la sequenza di escape \ uXXXX.
Jacob il

@zupa, Un altro problema è ... cosa significa " tranneCTLs "? Vuol dire i personaggi CR, LFsono consentiti? O significa solo la sequenza continua " CR LF SP/ HT" è consentita? (In altre parole, in grado di intestazione valori contengono un singolo CRo di LFo di HTvalori di intestazione può contenere i caratteri? CR, LFE HTin qualsiasi ordine e la quantità?)
Pacerier
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.