Какую кодировку символов следует использовать для заголовка HTTP?

122

Я использую «забавный» специальный символ HTML (✰) (см. Http://html5boilerplate.com/ для получения дополнительной информации) для ServerHTTP-заголовка, и мне интересно, «разрешено» ли это согласно спецификации.

  • Используя вкладку «Сеть» в инструментах разработчика в Chrome в Windows Xp Pro SP 3, я вижу ✰ нормально.

  • В IE8 ✰ это не вынесено правильно.

  • Валидатор HTML w3.org не отображает его правильно ( â°вместо этого отображает " ").

Я не слишком увлекаюсь кодировками символов ... и, честно говоря, я не особо забочусь о них; Я просто слепо использую UTF-8, потому что мне сказали. :-)


Вызвано ли несоответствие ошибками в разных парсерах / браузерах / движках / (как бы они ни назывались)?

Есть ли для этого спецификация или, может быть, список разрешенных символов для «значения» HTTP-заголовка?

Дэвид Мердок
источник
29
Этот вопрос лучше задать в общем: «Какие символы разрешены в значении заголовка http»
Акрикос
2
«Теперь я не слишком увлечен кодировками символов ... и, честно говоря, я не особо забочусь о них; я просто слепо использую UTF-8, потому что мне сказали :-)» <--- - Обязательная ссылка на joelonsoftware.com/2003/10/08/…
d4nyll 02

Ответы:

124

Вкратце: гарантированно работает только ASCII. Некоторые байты, отличные от ASCII, разрешены для обратной совместимости, но не должны отображаться.

HTTPbis сдался и уточнил, что в заголовках нет полезной кодировки, кроме ASCII:

Исторически сложилось так, что HTTP разрешил содержимое поля с текстом в кодировке ISO-8859-1 [ISO-8859-1], поддерживая другие кодировки только за счет использования кодировки [RFC2047]. На практике для большинства значений полей заголовка HTTP используется только подмножество кодировки US-ASCII [USASCII]. Вновь определенные поля заголовка ДОЛЖНЫ ограничивать значения своих полей октетами US-ASCII. Получатель ДОЛЖЕН обрабатывать другие октеты в содержимом поля (obs-text) как непрозрачные данные.


Ранее RFC 2616 от 1999 определял это:

Слова * TEXT МОГУТ содержать символы из наборов символов, отличных от ISO-8859-1 [22], только при кодировании в соответствии с правилами RFC 2047 [14].

а RFC 2047 - это кодировка MIME , поэтому это будет:

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

но я не думаю, что многие (если таковые имеются) клиенты его поддерживают.

Корнель
источник
7
Так что это значит? "✰" допустимо / разрешено?
Дэвид Мердок
8
Чтобы немного расширить очень полезный ответ: «UTF-8» - это набор символов, а «Q» означает, что значение будет «цитируемым-печатным». "B" также можно использовать, если вы хотите кодировать значение BASE64.
GargantuChet
1
@porneL, так что значит "непрозрачные данные"? Что именно должен делать получатель HTTP , когда он получает эти «непрозрачные данные»?
Pacerier
1
@Pacerier «непрозрачные данные» означает, что это черный ящик с кучей байтов, которые приложения не должны пытаться отображать или интерпретировать (например, двоичные данные). Что с ним происходит, зависит от заголовка, может варьироваться от «ничего» до «отбросить».
Kornel
@Kornel, кстати почему ты сменил логин на kornel?
Pacerier
10

Пожалуйста, сначала прочитайте комментарии, этот ответ, вероятно, делает неправильные выводы из правильных источников, требует редактирования.


Вы можете использовать любые печатаемые символы ASCII и не использовать специальные символы, такие как ✰ (который не является ASCII )

Совет : в JSON можно кодировать все, что угодно.

Изменить : сначала может быть неочевидно, кодировка символов, определенная в заголовке, применяется только для тела ответа, а не для самого заголовка. (Так как это может вызвать проблемы с курицей и яйцом.)


Я хотел бы суммировать все соответствующие определения согласно спецификации, связанной с Penchant.

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

Итак, мы ищем значение поля .

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 расшифровывается как Linear White Space. По сути, LWS - это пробел или табуляция, но вы можете разбить значение поля на несколько строк, начав новую строку перед пробелом или табуляцией.

Давайте упростим это до следующего:

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

Теперь нам нужно содержимое поля .

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

ТЕКСТ является наиболее общим и включает в себя все остальное, так что забудьте об остальном. Вот кодировка US-ASCII (= ASCII)

Как видите, разрешены все печатаемые символы ASCII.

Зупа
источник
3
Вы противоречите процитированным вами отрывкам. Почему вы говорите «и никаких специальных символов вроде»? Специальные символы - это просто OCTETs, а Since TEXT- любое, OCTETкроме 0 - 31, это означает, что разрешены все OCTETs от 32до . В октета ✰ есть , и и все три из них допускаются, поэтому ✰ допускается в соответствии с проходами вы цитируемых. 255 226156176
Pacerier
2
@Pacerier, ты, кажется, совершенно прав, я не понимаю, почему я пришел к такому выводу.
zupa
@Pacerier, но я не готов редактировать его, так как мне нужно было еще раз проверить спецификацию. Боюсь, что дополнительные детали ограничиваются кодировкой US-ASCII, которая, в свою очередь, поддерживает вывод, но делает рассуждения недостаточными.
zupa
1
Сказать, что «вы можете кодировать что угодно в JSON», - это немного вводит в заблуждение. JSON позволяет использовать символы Unicode, тогда как заголовки HTTP должны быть US-ASCII. Символы Unicode будут рассматриваться как «непрозрачные» данные, и поэтому их поведение не определено спецификацией HTTP. При этом JSON можно сделать безопасным для включения в заголовок HTTP, экранируя символы Unicode с помощью escape-последовательности \ uXXXX.
Джейкоб
@zupa, Другой вопрос ... что значит " кромеCTLs "? Означает ли это символы CR, LFкоторые разрешены? Или это означает, что разрешена только непрерывная последовательность " CR LF SP/ HT"? (Другими словами, может заголовок значения содержат один CRили LFили HTзначения заголовка может содержать символы? CR, LFИ HTв любом порядке и количестве?)
Pacerier